diff --git a/docs/balatrobot-api.md b/docs/balatrobot-api.md index 0c899e5..8cc6f9a 100644 --- a/docs/balatrobot-api.md +++ b/docs/balatrobot-api.md @@ -6,6 +6,8 @@ The API is organized into several key components: the `BalatroClient` for managi ## Client +The `BalatroClient` is the main interface for communicating with the Balatro game through TCP connections. It handles connection management, message serialization, and error handling. + ::: balatrobot.client.BalatroClient options: heading_level: 3 @@ -69,8 +71,16 @@ The API is organized into several key components: the `BalatroClient` for managi ## Models +The BalatroBot API uses Pydantic models to provide type-safe data structures that exactly match the game's internal state representation. All models inherit from `BalatroBaseModel` which provides consistent validation and serialization. + +#### Base Model + +::: balatrobot.models.BalatroBaseModel + ### Request Models +These models define the structure for specific API requests: + ::: balatrobot.models.StartRunRequest ::: balatrobot.models.BlindActionRequest ::: balatrobot.models.HandActionRequest @@ -78,15 +88,49 @@ The API is organized into several key components: the `BalatroClient` for managi ### Game State Models -::: balatrobot.models.Card -::: balatrobot.models.Game -::: balatrobot.models.GameState +The game state models provide comprehensive access to all Balatro game information, structured hierarchically to match the Lua API: + +#### Root Game State + +::: balatrobot.models.G + +#### Game Information + +::: balatrobot.models.GGame +::: balatrobot.models.GGameCurrentRound +::: balatrobot.models.GGameLastBlind +::: balatrobot.models.GGamePreviousRound +::: balatrobot.models.GGameProbabilities +::: balatrobot.models.GGamePseudorandom +::: balatrobot.models.GGameRoundBonus +::: balatrobot.models.GGameRoundScores +::: balatrobot.models.GGameSelectedBack +::: balatrobot.models.GGameShop +::: balatrobot.models.GGameStartingParams +::: balatrobot.models.GGameTags + +#### Hand Management + +::: balatrobot.models.GHand +::: balatrobot.models.GHandCards +::: balatrobot.models.GHandCardsBase +::: balatrobot.models.GHandCardsConfig +::: balatrobot.models.GHandCardsConfigCard +::: balatrobot.models.GHandConfig + +#### Joker Information + +::: balatrobot.models.GJokersCards +::: balatrobot.models.GJokersCardsConfig ### Communication Models -::: balatrobot.models.ErrorResponse +These models handle the communication protocol between your bot and the game: + ::: balatrobot.models.APIRequest ::: balatrobot.models.APIResponse +::: balatrobot.models.ErrorResponse +::: balatrobot.models.JSONLLogEntry ## Usage Examples diff --git a/src/balatrobot/__init__.py b/src/balatrobot/__init__.py index 106ee9d..86ad5da 100644 --- a/src/balatrobot/__init__.py +++ b/src/balatrobot/__init__.py @@ -3,7 +3,7 @@ from .client import BalatroClient from .enums import Actions, Decks, Stakes, State from .exceptions import BalatroError -from .models import GameState +from .models import G __version__ = "0.5.0" __all__ = [ @@ -17,5 +17,5 @@ # Exception "BalatroError", # Models - "GameState", + "G", ] diff --git a/src/balatrobot/models.py b/src/balatrobot/models.py index 46c4db4..e732399 100644 --- a/src/balatrobot/models.py +++ b/src/balatrobot/models.py @@ -1,8 +1,8 @@ -"""Pydantic models for BalatroBot API requests and responses.""" +"""Pydantic models for BalatroBot API matching Lua types structure.""" from typing import Any, Literal -from pydantic import BaseModel, ConfigDict, Field +from pydantic import BaseModel, ConfigDict, Field, field_validator from .enums import State @@ -11,14 +11,18 @@ class BalatroBaseModel(BaseModel): """Base model for all BalatroBot API models.""" model_config = ConfigDict( - extra="forbid", + extra="allow", str_strip_whitespace=True, validate_assignment=True, frozen=True, ) -# Request Models +# ============================================================================= +# Request Models (keep existing - they match Lua argument types) +# ============================================================================= + + class StartRunRequest(BalatroBaseModel): """Request model for starting a new run.""" @@ -53,59 +57,317 @@ class ShopActionRequest(BalatroBaseModel): action: Literal["next_round"] = Field(..., description="Shop action to perform") -# Response Models -class Card(BalatroBaseModel): - """Model for a playing card.""" +# ============================================================================= +# Game State Models (matching src/lua/types.lua) +# ============================================================================= + + +class GGameTags(BalatroBaseModel): + """Game tags model matching GGameTags in Lua types.""" + + key: str = Field("", description="Tag ID (e.g., 'tag_foil')") + name: str = Field("", description="Tag display name (e.g., 'Foil Tag')") + + +class GGameLastBlind(BalatroBaseModel): + """Last blind info matching GGameLastBlind in Lua types.""" + + boss: bool = Field(False, description="Whether the last blind was a boss") + name: str = Field("", description="Name of the last blind") + + +class GGameCurrentRound(BalatroBaseModel): + """Current round info matching GGameCurrentRound in Lua types.""" + + discards_left: int = Field(0, description="Number of discards remaining") + discards_used: int = Field(0, description="Number of discards used") + hands_left: int = Field(0, description="Number of hands remaining") + hands_played: int = Field(0, description="Number of hands played") + voucher: dict[str, Any] = Field( + default_factory=dict, description="Vouchers for this round" + ) + + @field_validator("voucher", mode="before") + @classmethod + def convert_empty_list_to_dict(cls, v): + """Convert empty list to empty dict.""" + return {} if v == [] else v + + +class GGameSelectedBack(BalatroBaseModel): + """Selected deck info matching GGameSelectedBack in Lua types.""" + + name: str = Field("", description="Name of the selected deck") + + +class GGameShop(BalatroBaseModel): + """Shop configuration matching GGameShop in Lua types.""" + + joker_max: int = Field(0, description="Maximum jokers in shop") + + +class GGameStartingParams(BalatroBaseModel): + """Starting parameters matching GGameStartingParams in Lua types.""" + + boosters_in_shop: int = Field(0, description="Number of boosters in shop") + reroll_cost: int = Field(0, description="Cost to reroll shop") + hand_size: int = Field(0, description="Starting hand size") + hands: int = Field(0, description="Starting hands per round") + ante_scaling: int = Field(0, description="Ante scaling factor") + consumable_slots: int = Field(0, description="Number of consumable slots") + dollars: int = Field(0, description="Starting money") + discards: int = Field(0, description="Starting discards per round") + joker_slots: int = Field(0, description="Number of joker slots") + vouchers_in_shop: int = Field(0, description="Number of vouchers in shop") - config: dict[str, Any] = Field(..., description="Card configuration data") - label: str = Field(..., description="Card label") +class GGamePreviousRound(BalatroBaseModel): + """Previous round info matching GGamePreviousRound in Lua types.""" -class Game(BalatroBaseModel): - """Model for game information.""" + dollars: int = Field(0, description="Dollars from previous round") - blind_on_deck: str | None = Field(None, description="Current blind on deck") - hands_played: int = Field(0, description="Number of hands played this round") - current_round: dict[str, Any] = Field( - default_factory=dict, description="Current round information" + +class GGameProbabilities(BalatroBaseModel): + """Game probabilities matching GGameProbabilities in Lua types.""" + + normal: float = Field(1.0, description="Normal probability modifier") + + +class GGamePseudorandom(BalatroBaseModel): + """Pseudorandom data matching GGamePseudorandom in Lua types.""" + + seed: str = Field("", description="Pseudorandom seed") + + +class GGameRoundBonus(BalatroBaseModel): + """Round bonus matching GGameRoundBonus in Lua types.""" + + next_hands: int = Field(0, description="Bonus hands for next round") + discards: int = Field(0, description="Bonus discards") + + +class GGameRoundScores(BalatroBaseModel): + """Round scores matching GGameRoundScores in Lua types.""" + + cards_played: dict[str, Any] = Field( + default_factory=dict, description="Cards played stats" + ) + cards_discarded: dict[str, Any] = Field( + default_factory=dict, description="Cards discarded stats" + ) + furthest_round: dict[str, Any] = Field( + default_factory=dict, description="Furthest round stats" + ) + furthest_ante: dict[str, Any] = Field( + default_factory=dict, description="Furthest ante stats" + ) + + +class GGame(BalatroBaseModel): + """Game state matching GGame in Lua types.""" + + bankrupt_at: int = Field(0, description="Money threshold for bankruptcy") + base_reroll_cost: int = Field(0, description="Base cost for rerolling shop") + blind_on_deck: str = Field("", description="Current blind type") + bosses_used: dict[str, int] = Field( + default_factory=dict, description="Bosses used in run" + ) + chips: int = Field(0, description="Current chip count") + current_round: GGameCurrentRound | None = Field( + None, description="Current round information" ) - skips: int = Field(0, description="Number of skips available") discount_percent: int = Field(0, description="Shop discount percentage") - interest_cap: int = Field(0, description="Interest cap amount") - chips: int = Field(0, description="Current chips") - inflation: int = Field(0, description="Current inflation amount") - round: int = Field(0, description="Current round number") dollars: int = Field(0, description="Current money amount") - max_jokers: int = Field(0, description="Maximum number of jokers") - bankrupt_at: int = Field(0, description="Bankrupt threshold") + hands_played: int = Field(0, description="Total hands played in the run") + inflation: int = Field(0, description="Current inflation rate") + interest_amount: int = Field(0, description="Interest amount per dollar") + interest_cap: int = Field(0, description="Maximum interest that can be earned") + last_blind: GGameLastBlind | None = Field( + None, description="Last blind information" + ) + max_jokers: int = Field(0, description="Maximum number of jokers allowed") + planet_rate: int = Field(0, description="Probability for planet cards in shop") + playing_card_rate: int = Field( + 0, description="Probability for playing cards in shop" + ) + previous_round: GGamePreviousRound | None = Field( + None, description="Previous round information" + ) + probabilities: GGameProbabilities | None = Field( + None, description="Various game probabilities" + ) + pseudorandom: GGamePseudorandom | None = Field( + None, description="Pseudorandom seed data" + ) + round: int = Field(0, description="Current round number") + round_bonus: GGameRoundBonus | None = Field( + None, description="Round bonus information" + ) + round_scores: GGameRoundScores | None = Field( + None, description="Round scoring data" + ) + seeded: bool = Field(False, description="Whether the run uses a seed") + selected_back: GGameSelectedBack | None = Field( + None, description="Selected deck information" + ) + shop: GGameShop | None = Field(None, description="Shop configuration") + skips: int = Field(0, description="Number of skips used") + smods_version: str = Field("", description="SMODS version") + stake: int = Field(0, description="Current stake level") + starting_params: GGameStartingParams | None = Field( + None, description="Starting parameters" + ) + tags: list[GGameTags] = Field(default_factory=list, description="Array of tags") + tarot_rate: int = Field(0, description="Probability for tarot cards in shop") + uncommon_mod: int = Field(0, description="Modifier for uncommon joker probability") + unused_discards: int = Field(0, description="Unused discards from previous round") + used_vouchers: dict[str, bool] | list = Field( + default_factory=dict, description="Vouchers used in run" + ) + voucher_text: str = Field("", description="Voucher text display") + win_ante: int = Field(0, description="Ante required to win") + won: bool = Field(False, description="Whether the run is won") + + @field_validator("bosses_used", "used_vouchers", mode="before") + @classmethod + def convert_empty_list_to_dict(cls, v): + """Convert empty list to empty dict.""" + return {} if v == [] else v + + @field_validator( + "previous_round", + "probabilities", + "pseudorandom", + "round_bonus", + "round_scores", + "shop", + "starting_params", + mode="before", + ) + @classmethod + def convert_empty_list_to_none(cls, v): + """Convert empty list to None for optional nested objects.""" + return None if v == [] else v + + +class GHandCardsBase(BalatroBaseModel): + """Hand card base properties matching GHandCardsBase in Lua types.""" + + id: Any = Field(None, description="Card ID") + name: str = Field("", description="Base card name") + nominal: str = Field("", description="Nominal value") + original_value: str = Field("", description="Original card value") + suit: str = Field("", description="Card suit") + times_played: int = Field(0, description="Times this card has been played") + value: str = Field("", description="Current card value") + + @field_validator("nominal", "original_value", "value", mode="before") + @classmethod + def convert_int_to_string(cls, v): + """Convert integer values to strings.""" + return str(v) if isinstance(v, int) else v + + +class GHandCardsConfigCard(BalatroBaseModel): + """Hand card config card data matching GHandCardsConfigCard in Lua types.""" + + name: str = Field("", description="Card name") + suit: str = Field("", description="Card suit") + value: str = Field("", description="Card value") + + +class GHandCardsConfig(BalatroBaseModel): + """Hand card configuration matching GHandCardsConfig in Lua types.""" + + card_key: str = Field("", description="Unique card identifier") + card: GHandCardsConfigCard | None = Field(None, description="Card-specific data") + + +class GHandCards(BalatroBaseModel): + """Hand card matching GHandCards in Lua types.""" + label: str = Field("", description="Display label of the card") + base: GHandCardsBase | None = Field(None, description="Base card properties") + config: GHandCardsConfig | None = Field(None, description="Card configuration") + debuff: bool = Field(False, description="Whether card is debuffed") + facing: str = Field("front", description="Card facing direction") + highlighted: bool = Field(False, description="Whether card is highlighted") -class GameState(BalatroBaseModel): - """Model for the complete game state.""" - state: int = Field(..., description="Current game state as integer") - game: Game | None = Field(None, description="Game information") - hand: list[Card] = Field(default_factory=list, description="Cards in hand") - jokers: list[dict[str, Any]] = Field( - default_factory=list, description="Joker cards" +class GHandConfig(BalatroBaseModel): + """Hand configuration matching GHandConfig in Lua types.""" + + card_count: int = Field(0, description="Number of cards in hand") + card_limit: int = Field(0, description="Maximum cards allowed in hand") + highlighted_limit: int = Field( + 0, description="Maximum cards that can be highlighted" + ) + + +class GHand(BalatroBaseModel): + """Hand structure matching GHand in Lua types.""" + + cards: list[GHandCards] = Field( + default_factory=list, description="Array of cards in hand" ) + config: GHandConfig | None = Field(None, description="Hand configuration") + + +class GJokersCardsConfig(BalatroBaseModel): + """Joker card configuration matching GJokersCardsConfig in Lua types.""" + + center: dict[str, Any] = Field( + default_factory=dict, description="Center configuration for joker" + ) + + +class GJokersCards(BalatroBaseModel): + """Joker card matching GJokersCards in Lua types.""" + + label: str = Field("", description="Display label of the joker") + config: GJokersCardsConfig | None = Field(None, description="Joker configuration") + + +class G(BalatroBaseModel): + """Root game state response matching G in Lua types.""" + + state: Any = Field(None, description="Current game state enum value") + game: GGame | None = Field( + None, description="Game information (null if not in game)" + ) + hand: GHand | None = Field( + None, description="Hand information (null if not available)" + ) + jokers: list[GJokersCards] | dict[str, Any] = Field( + default_factory=list, description="Jokers structure (can be list or dict)" + ) + + @field_validator("hand", mode="before") + @classmethod + def convert_empty_list_to_none_for_hand(cls, v): + """Convert empty list to None for hand field.""" + return None if v == [] else v @property - def state_enum(self) -> State: + def state_enum(self) -> State | None: """Get the state as an enum value.""" - return State(self.state) + return State(self.state) if self.state is not None else None class ErrorResponse(BalatroBaseModel): - """Model for API error responses.""" + """Model for API error responses matching Lua ErrorResponse.""" error: str = Field(..., description="Error message") error_code: str = Field(..., description="Standardized error code") - state: int = Field(..., description="Current game state when error occurred") + state: Any = Field(..., description="Current game state when error occurred") context: dict[str, Any] | None = Field(None, description="Additional error context") +# ============================================================================= # API Message Models +# ============================================================================= + + class APIRequest(BalatroBaseModel): """Model for API requests sent to the game.""" @@ -123,7 +385,6 @@ class APIResponse(BalatroBaseModel): model_config = ConfigDict(extra="allow") -# JSONL Log Entry class JSONLLogEntry(BalatroBaseModel): """Model for JSONL log entries that record game actions.""" @@ -135,7 +396,7 @@ class JSONLLogEntry(BalatroBaseModel): ..., description="The game function that was called", ) - game_state: GameState = Field( + game_state: G = Field( ..., description="Complete game state before the function execution", ) diff --git a/src/lua/api.lua b/src/lua/api.lua index 371f4f4..b28c017 100644 --- a/src/lua/api.lua +++ b/src/lua/api.lua @@ -104,6 +104,7 @@ function API.update(_) -- Process pending requests for key, request in pairs(API.pending_requests) do + ---@cast request PendingRequest if request.condition() then request.action() API.pending_requests[key] = nil @@ -119,6 +120,7 @@ function API.update(_) API.send_error_response("Invalid JSON", ERROR_CODES.INVALID_JSON) return end + ---@cast data APIRequest if data.name == nil then API.send_error_response("Message must contain a name", ERROR_CODES.MISSING_NAME) elseif data.arguments == nil then @@ -167,14 +169,13 @@ end ---@param context? table Optional additional context about the error function API.send_error_response(message, error_code, context) sendErrorMessage(message, "API") + ---@type ErrorResponse local response = { error = message, error_code = error_code, state = G.STATE, + context = context, } - if context then - response.context = context - end API.send_response(response) end @@ -281,6 +282,7 @@ API.functions["start_run"] = function(args) G.FUNCS.start_run(nil, { stake = args.stake, seed = args.seed, challenge = challenge_obj }) -- Defer sending response until the run has started + ---@type PendingRequest API.pending_requests["start_run"] = { condition = function() return G.STATE == G.STATES.BLIND_SELECT @@ -341,6 +343,7 @@ API.functions["skip_or_select_blind"] = function(args) if args.action == "select" then local button = blind_pane:get_UIE_by_ID("select_blind_button") G.FUNCS.select_blind(button) + ---@type PendingRequest API.pending_requests["skip_or_select_blind"] = { condition = function() return G.GAME and G.GAME.facing_blind and G.STATE == G.STATES.SELECTING_HAND @@ -355,6 +358,7 @@ API.functions["skip_or_select_blind"] = function(args) local tag_element = blind_pane:get_UIE_by_ID("tag_" .. current_blind) local button = tag_element.children[2] G.FUNCS.skip_blind(button) + ---@type PendingRequest API.pending_requests["skip_or_select_blind"] = { condition = function() local prev_state = { @@ -462,6 +466,7 @@ API.functions["play_hand_or_discard"] = function(args) end -- Defer sending response until the run has started + ---@type PendingRequest API.pending_requests["play_hand_or_discard"] = { condition = function() if #G.E_MANAGER.queues.base < EVENT_QUEUE_THRESHOLD and G.STATE_COMPLETE then @@ -500,6 +505,7 @@ API.functions["cash_out"] = function(_) end G.FUNCS.cash_out({ config = {} }) + ---@type PendingRequest API.pending_requests["cash_out"] = { condition = function() return G.STATE == G.STATES.SHOP and #G.E_MANAGER.queues.base < EVENT_QUEUE_THRESHOLD and G.STATE_COMPLETE @@ -537,6 +543,7 @@ API.functions["shop"] = function(args) local action = args.action if action == "next_round" then G.FUNCS.toggle_shop({}) + ---@type PendingRequest API.pending_requests["shop"] = { condition = function() return G.STATE == G.STATES.BLIND_SELECT diff --git a/src/lua/types.lua b/src/lua/types.lua index d24f83d..e268ef1 100644 --- a/src/lua/types.lua +++ b/src/lua/types.lua @@ -69,44 +69,145 @@ -- Game Entity Types (used in utils.lua for state extraction) -- ============================================================================= ----@class CardConfig ----@field name string The name of the card ----@field suit string The suit of the card ----@field value string The value/rank of the card ----@field card_key string Unique identifier for the card - ----@class Card ----@field label string The display label of the card ----@field config table Card configuration data - ----@class HandCard : Card ----@field config.card CardConfig Card-specific configuration - ----@class JokerCard : Card ----@field config.center table Center configuration for joker cards - ----@class GameRound ----@field discards_left number Number of discards remaining in the current round +-- Root game state response (G object) +---@class G +---@field state any Current game state enum value +---@field game? GGame Game information (null if not in game) +---@field hand? GHand Hand information (null if not available) +---@field jokers GJokersCards[] Array of joker cards ----@class GameState ----@field hands_played number Total hands played in the run ----@field skips number Number of skips used ----@field round number Current round number +-- Game state (G.GAME) +---@class GGame +---@field bankrupt_at number Money threshold for bankruptcy +---@field base_reroll_cost number Base cost for rerolling shop +---@field blind_on_deck string Current blind type ("Small", "Big", "Boss") +---@field bosses_used table Bosses used in run (bl_ = 1|0) +---@field chips number Current chip count +---@field current_round GGameCurrentRound Current round information ---@field discount_percent number Shop discount percentage ----@field interest_cap number Maximum interest that can be earned ----@field inflation number Current inflation rate ---@field dollars number Current money amount +---@field hands_played number Total hands played in the run +---@field inflation number Current inflation rate +---@field interest_amount number Interest amount per dollar +---@field interest_cap number Maximum interest that can be earned +---@field last_blind GGameLastBlind Last blind information ---@field max_jokers number Maximum number of jokers allowed ----@field bankrupt_at number Money threshold for bankruptcy ----@field chips number Current chip count ----@field blind_on_deck string Current blind type ("Small", "Large", "Boss") ----@field current_round GameRound Current round information - ----@class GameStateResponse ----@field state any Current game state enum value ----@field game? GameState Game information (null if not in game) ----@field hand? HandCard[] Array of cards in hand (null if not available) ----@field jokers JokerCard[] Array of joker cards +---@field planet_rate number Probability for planet cards in shop +---@field playing_card_rate number Probability for playing cards in shop +---@field previous_round GGamePreviousRound Previous round information +---@field probabilities GGameProbabilities Various game probabilities +---@field pseudorandom GGamePseudorandom Pseudorandom seed data +---@field round number Current round number +---@field round_bonus GGameRoundBonus Round bonus information +---@field round_scores GGameRoundScores Round scoring data +---@field seeded boolean Whether the run uses a seed +---@field selected_back GGameSelectedBack Selected deck information +---@field shop GGameShop Shop configuration +---@field skips number Number of skips used +---@field smods_version string SMODS version +---@field stake number Current stake level +---@field starting_params GGameStartingParams Starting parameters +---@field tags GGameTags[] Array of tags +---@field tarot_rate number Probability for tarot cards in shop +---@field uncommon_mod number Modifier for uncommon joker probability +---@field unused_discards number Unused discards from previous round +---@field used_vouchers table Vouchers used in run +---@field voucher_text string Voucher text display +---@field win_ante number Ante required to win +---@field won boolean Whether the run is won + +-- Game tags (G.GAME.tags[]) +---@class GGameTags +---@field key string Tag ID (e.g., "tag_foil") +---@field name string Tag display name (e.g., "Foil Tag") + +-- Last blind info (G.GAME.last_blind) +---@class GGameLastBlind +---@field boss boolean Whether the last blind was a boss +---@field name string Name of the last blind + +-- Current round info (G.GAME.current_round) +---@class GGameCurrentRound +---@field discards_left number Number of discards remaining +---@field discards_used number Number of discards used +---@field hands_left number Number of hands remaining +---@field hands_played number Number of hands played +---@field voucher table Vouchers for this round + +-- Selected deck info (G.GAME.selected_back) +---@class GGameSelectedBack +---@field name string Name of the selected deck + +-- Shop configuration (G.GAME.shop) +---@class GGameShop + +-- Starting parameters (G.GAME.starting_params) +---@class GGameStartingParams + +-- Previous round info (G.GAME.previous_round) +---@class GGamePreviousRound + +-- Game probabilities (G.GAME.probabilities) +---@class GGameProbabilities + +-- Pseudorandom data (G.GAME.pseudorandom) +---@class GGamePseudorandom + +-- Round bonus (G.GAME.round_bonus) +---@class GGameRoundBonus + +-- Round scores (G.GAME.round_scores) +---@class GGameRoundScores + +-- Hand structure (G.hand) +---@class GHand +---@field cards GHandCards[] Array of cards in hand +---@field config GHandConfig Hand configuration + +-- Hand configuration (G.hand.config) +---@class GHandConfig +---@field card_count number Number of cards in hand +---@field card_limit number Maximum cards allowed in hand +---@field highlighted_limit number Maximum cards that can be highlighted + +-- Hand card (G.hand.cards[]) +---@class GHandCards +---@field label string Display label of the card +---@field base GHandCardsBase Base card properties +---@field config GHandCardsConfig Card configuration +---@field debuff boolean Whether card is debuffed +---@field facing string Card facing direction ("front", etc.) +---@field highlighted boolean Whether card is highlighted + +-- Hand card base properties (G.hand.cards[].base) +---@class GHandCardsBase +---@field id any Card ID +---@field name string Base card name +---@field nominal string Nominal value +---@field original_value string Original card value +---@field suit string Card suit +---@field times_played number Times this card has been played +---@field value string Current card value + +-- Hand card configuration (G.hand.cards[].config) +---@class GHandCardsConfig +---@field card_key string Unique card identifier +---@field card GHandCardsConfigCard Card-specific data + +-- Hand card config card data (G.hand.cards[].config.card) +---@class GHandCardsConfigCard +---@field name string Card name +---@field suit string Card suit +---@field value string Card value + +-- Joker card (G.jokers.cards[]) +---@class GJokersCards +---@field label string Display label of the joker +---@field config GJokersCardsConfig Joker configuration + +-- Joker card configuration (G.jokers.cards[].config) +---@class GJokersCardsConfig +---@field center table Center configuration for joker -- ============================================================================= -- Utility Module (implemented in utils.lua) @@ -114,7 +215,7 @@ ---Utility functions for game state extraction and data processing ---@class utils ----@field get_game_state fun(): GameStateResponse Extracts the current game state +---@field get_game_state fun(): G Extracts the current game state ---@field table_to_json fun(obj: any, depth?: number): string Converts a Lua table to JSON string -- ============================================================================= @@ -124,7 +225,7 @@ ---@class LogEntry ---@field timestamp_ms number Timestamp in milliseconds since epoch ---@field function {name: string, arguments: table} Function call information ----@field game_state GameStateResponse Game state at time of logging +---@field game_state G Game state at time of logging -- ============================================================================= -- Configuration Types (used in balatrobot.lua) diff --git a/src/lua/utils.lua b/src/lua/utils.lua index 81358e3..de4231b 100644 --- a/src/lua/utils.lua +++ b/src/lua/utils.lua @@ -4,48 +4,365 @@ local json = require("json") -- ========================================================================== -- Game State Extraction +-- +-- In the following code there are a lot of comments which document the +-- process of understanding the game state. There are many fields that +-- we are not interested for BalatroBot. I leave the comments here for +-- future reference. +-- +-- The proper documnetation of the game state is available in the types.lua +-- file (src/lua/types.lua). -- ========================================================================== ---Extracts the current game state including game info, hand, and jokers ----@return GameStateResponse The complete game state +---@return G game_state The complete game state function utils.get_game_state() + local tags = {} + if G.GAME.tags then + for i, tag in pairs(G.GAME.tags) do + tags[i] = { + -- There are a couples of fieds regarding UI. we are not intersted in that. + -- HUD_tag = table/list, -- ?? + -- ID = int -- id used in the UI or tag id? + -- ability = table/list, -- ?? + -- config = table/list, -- ?? + key = tag.key, -- id string of the tag (e.g. "tag_foil") + name = tag.name, -- text string of the tag (e.g. "Foil Tag") + -- pos = table/list, coords of the tags in the UI + -- tag_sprite = table/list, sprite of the tag for the UI + -- tally = int (default 0), -- ?? + -- triggered = bool (default false), -- false when the tag will be trigger in later stages. + -- For exaple double money trigger instantly and it's not even add to the tags talbe, + -- while other tags trigger in the next shop phase. + } + end + end + + local last_blind = { + boss = false, + name = "", + } + if G.GAME.last_blind then + last_blind = { + boss = G.GAME.last_blind.boss, -- bool. True if the last blind was a boss + name = G.GAME.last_blind.name, -- str (default "" before entering round 1) + -- When entering round 1, the last blind is set to "Small Blind". + -- So I think that the last blind refers to the blind selected in the most recent BLIND_SELECT state. + } + end + local game = nil if G.GAME then game = { - hands_played = G.GAME.hands_played, - skips = G.GAME.skips, - round = G.GAME.round, - discount_percent = G.GAME.discount_percent, - interest_cap = G.GAME.interest_cap, - inflation = G.GAME.inflation, - dollars = G.GAME.dollars, - max_jokers = G.GAME.max_jokers, + -- STOP_USE = int (default 0), -- ?? bankrupt_at = G.GAME.bankrupt_at, + -- banned_keys = table/list, -- ?? + base_reroll_cost = G.GAME.base_reroll_cost, + + -- blind = {}, This is active during the playing phase and contains + -- information about the UI of the blind object. It can be dragged around + -- We are not interested in it. + + blind_on_deck = G.GAME.blind_on_deck, -- Small | ?? | ?? + bosses_used = { + -- bl_ = int, 1 | 0 (default 0) + -- ... x 28 + -- In a normal ante there should be only one boss used, so only one value is one + }, + -- cards_played: table, change during game phase + chips = G.GAME.chips, - blind_on_deck = G.GAME.blind_on_deck, + -- chip_text = str, the text of the current chips in the UI + -- common_mod = int (default 1), -- prob that a common joker appear in the shop + + -- "consumeable_buffer": int, (default 0) -- number of cards in the consumeable buffer? + -- consumeable_usage = { }, -- table/list to track the consumable usage through the run. + -- "current_boss_streak": int, (default 0) -- in the simple round should be == to the ante? + -- + current_round = { - discards_left = G.GAME.current_round.discards_left, - hands_left = G.GAME.current_round.hands_left, + -- "ancient_card": { -- maybe some random card used by some joker/effect? idk + -- "suit": "Spades" | "Hearts" | "Diamonds" | "Clubs", + -- }, + -- any_hand_drawn = true, -- bool (default true) ?? + -- "cards_flipped": int, (Defualt 0) + -- "castle_card": { -- ?? + -- "suit": "Spades" | "Hearts" | "Diamonds" | "Clubs", + -- }, + + -- This should contains interesting info during playing phase + -- "current_hand": { + -- "chip_text": str, Default "-" + -- "chip_total": int, Default 0 + -- "chip_total_text: str , Default "" + -- "chips": int, Default 0 + -- "hand_level": str Default "" + -- "handname": str Default "" + -- "handname_text": str Default "" + -- "mult": int, Default 0 + -- "mult_text": str, Default "0" + -- }, + + discards_left = G.GAME.current_round.discards_left, -- Number of discards left for this round + discards_used = G.GAME.current_round.discards_used, -- int (default 0) Number of discard used in this round + + -- "dollars": int, (default 0) -- maybe dollars earned in this round? + -- "dollars_to_be_earned": str, (default "") -- ?? + -- "free_rerolls": int, (default 0) -- Number of free rerolls in the shop? + hands_left = G.GAME.current_round.hands_left, -- Number of hands left for this round + hands_played = G.GAME.current_round.hands_played, -- Number of hands played in this round + -- "idol_card": { -- what's a idol card?? maybe some random used by some joker/effect? idk + -- "rank": "Ace" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "10" | "Jack" | "Queen" | "King", + -- "suit": "Spades" | "Hearts" | "Diamonds" | "Clubs", + -- }, + -- "jokers_purchased": int, (default 0) -- Number of jokers purchased in this round ? + -- "mail_card": { -- what's a mail card?? maybe some random used by some joker/effect? idk + -- "id": int -- id of the mail card + -- "rank": str, -- + -- } + -- "most_played_poker_hand": str, (Default "High Card") + -- "reroll_cost": int, (default 5) + -- "reroll_cost_increase": int, (default 0) + -- "round_dollars": int, (default 0) ?? + -- "round_text": str, (default "Round ") + -- "used_packs": table/list, + voucher = { -- this is a list cuz some effect can give multiple vouchers per ante + -- "1": "v_hone", + -- "spawn": { + -- "v_hone": "..." + -- } + }, }, + + -- "disabled_ranks" = table/list, -- there are some boss that disable certain ranks + -- "disabled_suits" = table/list, -- there are some boss that disable certain suits + + discount_percent = G.GAME.discount_percent, -- int (default 0) this lower the price in the shop. A voucher must be redeemed + dollars = G.GAME.dollars, -- int , current dollars in the run + + -- "ecto_minus": int, + -- "edition_rate": int, (default 1) -- change the prob. to find a card which is not a base? + -- "hand_usage": table/list, (default {}) -- maybe track the hand played so far in the run? + + -- table/list. Maybe this track the various hand levels? + -- "hands": { + -- "Five of a Kind": {...}, + -- "Flush": { + -- "_saved_d_u": true, This is a private field so we are not interested in it + -- "chips": 35, current chips reward + -- "example": { + -- "1": "...", + -- "2": "...", + -- "3": "...", + -- "4": "...", + -- "5": "..." + -- }, + -- "l_chips": 15, boundary for chips? + -- "l_mult": 2, boundary for mult? + -- "level": 1, level of the hand + -- "mult": 4, curent mult reward + -- "order": 7, order for how good the hand is Five of a Kind is 1, High Card is 12 + -- "played": 0, how many time the hand has been played in this run + -- "played_this_round": 0, how many time the hand has been played in this round + -- "s_chips": 35, boundary for chips? + -- "s_mult": 4, boundary for mult? + -- "visible": true, is this hand visible in the Run Info interface + -- }, + -- "Flush Five": {...}, + -- "Flush House": {...}, + -- "Four of a Kind": {...}, + -- "Full House": {...}, + -- "High Card": {...}, + -- "Pair": {...}, + -- "Straight": {...}, + -- "Straight Flush": {...}, + -- "Three of a Kind": {...}, + -- "Two Pair": {...}, + -- }, + hands_played = G.GAME.hands_played, -- (default 0) hand played in this run + inflation = G.GAME.inflation, -- (default 0) maybe there are some stakes that increase the prices in the shop ? + interest_amount = G.GAME.interest_amount, -- (default 1) how much each $ is worth at the eval round stage + interest_cap = G.GAME.interest_cap, -- (default 25) cap for interest, e.g. 25 dollar means that every each 5 dollar you get one $ + + -- joker_buffer = int, -- (default 0) ?? + -- joker_rate = int, -- (default 20) prob that a joker appear in the shop + -- joker_usage = G.GAME.joker_usage, -- list/table maybe a list of jokers used in the run? + -- + last_blind = last_blind, + -- legendary_mod = G.GAME.legendary_mod, -- (default 1) maybe the probality/modifier to find a legendary joker in the shop? + + max_jokers = G.GAME.max_jokers, --(default 0) the total number of jokers slots? + + -- modifiers = list/table, -- ?? + -- orbital_choices = { -- what's an orbital choice?? This is a list (table with int keys). related to pseudorandom + -- -- 1: { + -- -- "Big": "Two Pair", + -- -- "Boss": "Three of a Kind", + -- -- "Small": "Full House" + -- -- } + -- }, + -- pack_size = G.GAME.pack_size (int default 2), -- number of pack slots ? + -- perishable_rounds = int (default 5), -- ?? + -- perscribed_bosses = list/table, -- ?? + + planet_rate = G.GAME.planet_rate, -- (int default 4) -- prob that a planet card appers in the shop + playing_card_rate = G.GAME.playing_card_rate, -- (int default 0) -- prob that a playing card appers in the shop. at the start of the run playable cards are not purchasable so it's 0, then by reedming a voucher, you can buy them in the shop. + -- pool_flags = list/table, -- ?? + + previous_round = { + -- I think that this table will contain the previous round info + -- "dollars": int, (default 4, this is the dollars amount when starting red deck white stake) + }, + probabilities = { + -- Maybe this table track various probabilities for various events (e.g. prob that planet cards appers in the + -- shop) + -- "normal": int, (default 1) + }, + + -- This table contains the seed used to start a run. The seed is used in the generation of pseudorandom number + -- which themselves are used to add randomness to a run. (e.g. which is the first tag? well the float that is + -- probably used to extract the tag for the first round is in Tag1.) + pseudorandom = { + -- float e.g. 0.1987752917732 (all the floats are in the range [0, 1) with 13 digit after the dot. + -- Tag1 = float, + -- Voucher1 = float, + -- Voucher1_resample2 = float, + -- Voucher1_resample3 = float, + -- anc1 = float, + -- boss = float, + -- cas1 = float, + -- hashed_seed = float, + -- idol1 = float, + -- mail1 = float, + -- orbital = float, + -- seed = string, This is the seed used to start a run + -- shuffle = float, + }, + -- rare_mod = G.GAME.rare_mod, (int default 1) -- maybe the probality/modifier to find a rare joker in the shop? + -- rental_rate = int (default 3), -- maybe the probality/modifier to find a rental card in the shop? + round = G.GAME.round, -- number of the current round. 0 before starting the first rounthe first round + round_bonus = { -- What's a "round_bonus"? Some bonus given at the end of the round? maybe use in the eval round phase + -- "discards": int, (default 0) ?? + -- "next_hands": int, (default 0) ?? + }, + + -- round_resets = table/list, -- const used to reset the round? but should be not relevant for our use case + round_scores = { + -- contains values used in the round eval phase? + -- "cards_discarded": { + -- "amt": int, (default 0) amount of cards discarded + -- "label": "Cards Discarded" label for the amount of cards discarded. maybe used in the interface + -- }, + -- "cards_played": {...}, amount of cards played in this round + -- "cards_purchased": {...}, amount of cards purchased in this round + -- "furthest_ante": {...}, furthest ante in this run + -- "furthest_round": {...}, furthest round in this round or run? + -- "hand": {...}, best hand in this round + -- "new_collection": {...}, new cards discovered in this round + -- "poker_hand": {...}, most played poker hand in this round + -- "times_rerolled": {...}, number of times rerolled in this round + }, + seeded = G.GAME.seeded, -- bool if the run use a seed or not + selected_back = { + -- The back should be the deck: Red Deck, Black Deck, etc. + -- This table contains functions and info about deck selection + -- effect = {} -- contains function e.g. "set" + -- loc_name = str, -- ?? (default "Red Deck") + name = G.GAME.selected_back.name, -- name of the deck + -- pos = {x = int (default 0), y = int (default 0)}, -- ?? + }, + -- seleted_back_key = table -- ?? + shop = { + -- contains info about the shop + -- joker_max = int (default 2), -- max number that can appear in the shop or the number of shop slots? + }, + skips = G.GAME.skips, -- number of skips in this run + smods_version = G.GAME.smods_version, -- version of smods loaded + -- sort = str, (default "desc") card sort order. descending (desc) or suit, I guess? + -- spectral_rate = int (default 0), -- prob that a spectral card appear in the shop + stake = G.GAME.stake, --int (default 1), -- the stake for the run (1 for White Stake, 2 for Red Stake ...) + -- starting_deck_size = int (default 52), -- the starting deck size for the run. + starting_params = { + -- The starting parmeters are maybe not relevant, we are intersted in + -- the actual values of the parameters + -- + -- ante_scaling = G.GAME.starting_params.ante_scaling, -- (default 1) increase the ante by one after boss defeated + -- boosters_in_shop = G.GAME.starting_params.boosters_in_shop, -- (default 2) Number of booster slots + -- consumable_slots = G.GAME.starting_params.consumable_slots, -- (default 2) Number of consumable slots + -- discard_limit = G.GAME.starting_params.discard_limit, -- (default 5) Number of cards to discard + -- ... + }, + + -- tag_tally = -- int (default 0), -- what's a tally? + tags = tags, + tarot_rate = G.GAME.tarot_rate, -- int (default 4), -- prob that a tarot card appear in the shop + uncommon_mod = G.GAME.uncommon_mod, -- int (default 1), -- prob that an uncommon joker appear in the shop + unused_discards = G.GAME.unused_discards, -- int (default 0), -- number of discards left at the of a round. This is used some time to in the eval round phase + -- used_jokers = { -- table/list to track the joker usage through the run ? + -- c_base = bool + -- } + used_vouchers = G.GAME.used_vouchers, -- table/list to track the voucher usage through the run. Should be the ones that can be see in "Run Info" + voucher_text = G.GAME.voucher_text, -- str (default ""), -- the text of the voucher for the current run + win_ante = G.GAME.win_ante, -- int (default 8), -- the ante for the win condition + won = G.GAME.won, -- bool (default false), -- true if the run is won (e.g. current ante > win_ante) } end local hand = nil if G.hand then - hand = {} + local cards = {} for i, card in pairs(G.hand.cards) do - hand[i] = { - label = card.label, + cards[i] = { + -- ability = table of card abilities effect, mult, extra_value + label = card.label, -- str (default "Base Card") | ... | ... | ? + -- playing_card = card.config.card.playing_card, -- int. The card index in the deck for the current round ? + -- sell_cost = card.sell_cost, -- int (default 1). The dollars you get if you sell this card ? + base = { + -- These should be the valude for the original base card + -- without any modifications + id = card.base.id, -- ?? + name = card.base.name, + nominal = card.base.nominal, + original_value = card.base.original_value, + suit = card.base.suit, + times_played = card.base.times_played, + value = card.base.value, + }, config = { + card_key = card.config.card_key, card = { name = card.config.card.name, suit = card.config.card.suit, value = card.config.card.value, - card_key = card.config.card_key, }, }, + debuff = card.debuff, + -- debuffed_by_blind = bool (default false). True if the card is debuffed by the blind + facing = card.facing, -- str (default "front") | ... | ... | ? + highlighted = card.highlighted, -- bool (default false). True if the card is highlighted } end + + hand = { + cards = cards, + config = { + card_count = G.hand.config.card_count, -- (int) number of cards in the hand + card_limit = G.hand.config.card_limit, -- (int) max number of cards in the hand + highlighted_limit = G.hand.config.highlighted_limit, -- (int) max number of highlighted cards in the hand + -- lr_padding ?? flaot + -- sort = G.hand.config.sort, -- (str) sort order of the hand. "desc" | ... | ? not really... idk + -- temp_limit ?? (int) + -- type ?? (Default "hand", str) + }, + -- container = table for UI elements. we are not interested in it + -- created_on_pause = bool ?? + -- highlighted = list of highlighted cards. This is a list of card. + -- hover_offset = table/list, coords of the hand in the UI. we are not interested in it. + -- last_aligned = int, ?? + -- last_moved = int, ?? + -- + -- There a a lot of other fields that we are not interested in ... + } end local jokers = {} @@ -81,6 +398,21 @@ end function utils.table_to_json(obj, depth) depth = depth or 3 + -- Fields to skip during serialization to avoid circular references and large data + local skip_fields = { + children = true, + parent = true, + velocity = true, + area = true, + alignment = true, + container = true, + h_popup = true, + role = true, + colour = true, + back_overlay = true, + center = true, + } + local function sanitize_for_json(value, current_depth) if current_depth <= 0 then return "..." @@ -100,7 +432,11 @@ function utils.table_to_json(obj, depth) local sanitized = {} for k, v in pairs(value) do local key = type(k) == "string" and k or tostring(k) - sanitized[key] = sanitize_for_json(v, current_depth - 1) + -- Skip keys that start with capital letters (UI-related) + -- Skip predefined fields to avoid circular references and large data + if not (type(key) == "string" and string.sub(key, 1, 1):match("[A-Z]")) and not skip_fields[key] then + sanitized[key] = sanitize_for_json(v, current_depth - 1) + end end return sanitized else diff --git a/tests/balatrobot/test_client.py b/tests/balatrobot/test_client.py index a28cb76..373b5f8 100644 --- a/tests/balatrobot/test_client.py +++ b/tests/balatrobot/test_client.py @@ -6,10 +6,10 @@ import pytest -from src.balatrobot.client import BalatroClient -from src.balatrobot.enums import State -from src.balatrobot.exceptions import BalatroError, ConnectionFailedError -from src.balatrobot.models import GameState +from balatrobot.client import BalatroClient +from balatrobot.enums import State +from balatrobot.exceptions import BalatroError, ConnectionFailedError +from balatrobot.models import G @pytest.fixture(scope="function", autouse=True) @@ -18,7 +18,7 @@ def reset_game_to_menu(): try: with BalatroClient() as client: response = client.send_message("go_to_menu", {}) - game_state = GameState.model_validate(response) + game_state = G.model_validate(response) assert game_state.state_enum == State.MENU except (ConnectionFailedError, BalatroError): # Game not running or other API error, skip setup @@ -54,8 +54,8 @@ def test_context_manager_with_game_running(self): # Test that we can get game state response = client.send_message("get_game_state", {}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) def test_manual_connect_disconnect_with_game_running(self): """Test manual connection and disconnection with game running.""" @@ -68,8 +68,8 @@ def test_manual_connect_disconnect_with_game_running(self): # Test that we can get game state response = client.send_message("get_game_state", {}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) # Test disconnection client.disconnect() @@ -80,9 +80,9 @@ def test_get_game_state_with_game_running(self): """Test getting game state with game running.""" with BalatroClient() as client: response = client.send_message("get_game_state", {}) - game_state = GameState.model_validate(response) + game_state = G.model_validate(response) - assert isinstance(game_state, GameState) + assert isinstance(game_state, G) assert hasattr(game_state, "state") def test_go_to_menu_with_game_running(self): @@ -90,9 +90,9 @@ def test_go_to_menu_with_game_running(self): with BalatroClient() as client: # Test go_to_menu from any state response = client.send_message("go_to_menu", {}) - game_state = GameState.model_validate(response) + game_state = G.model_validate(response) - assert isinstance(game_state, GameState) + assert isinstance(game_state, G) assert hasattr(game_state, "state") def test_double_connect_is_safe(self): @@ -170,8 +170,8 @@ def test_start_run_with_game_running(self): response = client.send_message( "start_run", {"deck": "Red Deck", "seed": "OOOO155"} ) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) # Test with all parameters response = client.send_message( @@ -183,26 +183,26 @@ def test_start_run_with_game_running(self): "challenge": "test_challenge", }, ) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) def test_skip_or_select_blind_with_game_running(self): """Test skip_or_select_blind method with game running.""" with BalatroClient() as client: # First start a run to get to blind selection state response = client.send_message("start_run", {"deck": "Red Deck"}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) # Test skip action response = client.send_message("skip_or_select_blind", {"action": "skip"}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) # Test select action response = client.send_message("skip_or_select_blind", {"action": "select"}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) def test_play_hand_or_discard_with_game_running(self): """Test play_hand_or_discard method with game running.""" @@ -212,8 +212,8 @@ def test_play_hand_or_discard_with_game_running(self): response = client.send_message( "play_hand_or_discard", {"action": "play_hand", "cards": [0, 1, 2]} ) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) except BalatroError: # Expected if game is not in selecting hand state pass @@ -223,8 +223,8 @@ def test_play_hand_or_discard_with_game_running(self): response = client.send_message( "play_hand_or_discard", {"action": "discard", "cards": [0]} ) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) except BalatroError: # Expected if game is not in selecting hand state pass @@ -234,8 +234,8 @@ def test_cash_out_with_game_running(self): with BalatroClient() as client: try: response = client.send_message("cash_out", {}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) except BalatroError: # Expected if game is not in correct state for cash out pass @@ -245,8 +245,8 @@ def test_shop_with_game_running(self): with BalatroClient() as client: try: response = client.send_message("shop", {"action": "next_round"}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) except BalatroError: # Expected if game is not in shop state pass @@ -328,25 +328,25 @@ def test_send_message_successful_response(self): # Test skip_or_select_blind success response = client.send_message("skip_or_select_blind", {"action": "skip"}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) # Test play_hand_or_discard success response = client.send_message( "play_hand_or_discard", {"action": "play_hand", "cards": [0, 1]} ) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) # Test cash_out success response = client.send_message("cash_out", {}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) # Test shop success response = client.send_message("shop", {"action": "next_round"}) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) class TestSendMessageAPIFunctions: @@ -357,10 +357,10 @@ def test_send_message_get_game_state(self): with BalatroClient() as client: response = client.send_message("get_game_state", {}) - # Response should be a dict that can be validated as GameState + # Response should be a dict that can be validated as G assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) assert hasattr(game_state, "state") def test_send_message_go_to_menu(self): @@ -369,8 +369,8 @@ def test_send_message_go_to_menu(self): response = client.send_message("go_to_menu", {}) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) assert hasattr(game_state, "state") def test_send_message_start_run_minimal(self): @@ -379,8 +379,8 @@ def test_send_message_start_run_minimal(self): response = client.send_message("start_run", {"deck": "Red Deck"}) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) def test_send_message_start_run_with_all_params(self): """Test send_message with start_run function (all parameters).""" @@ -396,8 +396,8 @@ def test_send_message_start_run_with_all_params(self): ) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) def test_send_message_skip_or_select_blind_skip(self): """Test send_message with skip_or_select_blind function (skip action).""" @@ -408,8 +408,8 @@ def test_send_message_skip_or_select_blind_skip(self): response = client.send_message("skip_or_select_blind", {"action": "skip"}) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) def test_send_message_skip_or_select_blind_select(self): """Test send_message with skip_or_select_blind function (select action).""" @@ -420,8 +420,8 @@ def test_send_message_skip_or_select_blind_select(self): response = client.send_message("skip_or_select_blind", {"action": "select"}) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) def test_send_message_play_hand_or_discard_play_hand(self): """Test send_message with play_hand_or_discard function (play_hand action).""" @@ -433,8 +433,8 @@ def test_send_message_play_hand_or_discard_play_hand(self): ) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) except BalatroError: # Expected if game is not in selecting hand state pass @@ -449,8 +449,8 @@ def test_send_message_play_hand_or_discard_discard(self): ) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) except BalatroError: # Expected if game is not in selecting hand state pass @@ -462,8 +462,8 @@ def test_send_message_cash_out(self): response = client.send_message("cash_out", {}) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) except BalatroError: # Expected if game is not in correct state for cash out pass @@ -475,8 +475,8 @@ def test_send_message_shop_next_round(self): response = client.send_message("shop", {"action": "next_round"}) assert isinstance(response, dict) - game_state = GameState.model_validate(response) - assert isinstance(game_state, GameState) + game_state = G.model_validate(response) + assert isinstance(game_state, G) except BalatroError: # Expected if game is not in shop state pass diff --git a/tests/balatrobot/test_exceptions.py b/tests/balatrobot/test_exceptions.py index 0ad136e..cff1cc3 100644 --- a/tests/balatrobot/test_exceptions.py +++ b/tests/balatrobot/test_exceptions.py @@ -1,7 +1,7 @@ """Tests for exception handling and error response creation.""" -from src.balatrobot.enums import ErrorCode -from src.balatrobot.exceptions import ( +from balatrobot.enums import ErrorCode +from balatrobot.exceptions import ( BalatroError, ConnectionFailedError, InvalidJSONError, diff --git a/tests/balatrobot/test_models.py b/tests/balatrobot/test_models.py index e21237c..d87c661 100644 --- a/tests/balatrobot/test_models.py +++ b/tests/balatrobot/test_models.py @@ -2,29 +2,29 @@ import pytest -from src.balatrobot.enums import State -from src.balatrobot.models import GameState +from balatrobot.enums import State +from balatrobot.models import G class TestGameState: - """Test suite for GameState model.""" + """Test suite for G model.""" def test_state_enum_property(self): """Test state_enum property converts integer to State enum correctly.""" # Test with valid state value - game_state = GameState(state=1, game=None) + game_state = G(state=1, game=None, hand=None) assert game_state.state_enum == State.SELECTING_HAND # Test with different state values - game_state = GameState(state=11, game=None) + game_state = G(state=11, game=None, hand=None) assert game_state.state_enum == State.MENU - game_state = GameState(state=5, game=None) + game_state = G(state=5, game=None, hand=None) assert game_state.state_enum == State.SHOP def test_state_enum_property_with_invalid_state(self): """Test state_enum property with invalid state value raises ValueError.""" - game_state = GameState(state=999, game=None) # Invalid state + game_state = G(state=999, game=None, hand=None) # Invalid state with pytest.raises(ValueError): _ = game_state.state_enum diff --git a/tests/lua/test_api_functions.py b/tests/lua/test_api_functions.py index 05e609d..216869d 100644 --- a/tests/lua/test_api_functions.py +++ b/tests/lua/test_api_functions.py @@ -209,7 +209,7 @@ def test_select_blind(self, tcp_client: socket.socket) -> None: assert game_state["state"] == State.SELECTING_HAND.value # Assert that there are 8 cards in the hand - assert len(game_state["hand"]) == 8 + assert len(game_state["hand"]["cards"]) == 8 def test_skip_blind(self, tcp_client: socket.socket) -> None: """Test skipping a blind during the blind selection phase.""" @@ -444,17 +444,17 @@ def test_play_hand( play_hand_args = {"action": "play_hand", "cards": cards} init_card_keys = [ - card["config"]["card"]["card_key"] for card in initial_game_state["hand"] + card["config"]["card_key"] for card in initial_game_state["hand"]["cards"] ] played_hand_keys = [ - initial_game_state["hand"][i]["config"]["card"]["card_key"] + initial_game_state["hand"]["cards"][i]["config"]["card_key"] for i in play_hand_args["cards"] ] game_state = send_and_receive_api_message( tcp_client, "play_hand_or_discard", play_hand_args ) final_card_keys = [ - card["config"]["card"]["card_key"] for card in game_state["hand"] + card["config"]["card_key"] for card in game_state["hand"]["cards"] ] assert game_state["state"] == State.SELECTING_HAND.value assert game_state["game"]["hands_played"] == 1 @@ -533,17 +533,17 @@ def test_discard( discard_hand_args = {"action": "discard", "cards": cards} init_card_keys = [ - card["config"]["card"]["card_key"] for card in initial_game_state["hand"] + card["config"]["card_key"] for card in initial_game_state["hand"]["cards"] ] discarded_hand_keys = [ - initial_game_state["hand"][i]["config"]["card"]["card_key"] + initial_game_state["hand"]["cards"][i]["config"]["card_key"] for i in discard_hand_args["cards"] ] game_state = send_and_receive_api_message( tcp_client, "play_hand_or_discard", discard_hand_args ) final_card_keys = [ - card["config"]["card"]["card_key"] for card in game_state["hand"] + card["config"]["card_key"] for card in game_state["hand"]["cards"] ] assert game_state["state"] == State.SELECTING_HAND.value assert game_state["game"]["hands_played"] == 0 diff --git a/tests/lua/test_runs.py b/tests/lua/test_runs.py index 5a5b0ec..dd8a3f8 100644 --- a/tests/lua/test_runs.py +++ b/tests/lua/test_runs.py @@ -61,7 +61,21 @@ def test_replay_run(self, tcp_client: socket.socket, jsonl_file: Path) -> None: next_step = steps[step_num + 1] expected_game_state = next_step["game_state"] - # Assert complete game state equality + # HACK: Remove highlighted field from cards before comparison + # The logger hook, log the game state after the card selection, + # so in the replay we have the highlighted cards, while the game_state + # before the action has the non-highlighted cards. + if "hand" in actual_game_state and "cards" in actual_game_state["hand"]: + for card in actual_game_state["hand"]["cards"]: + card.pop("highlighted", None) + if ( + "hand" in expected_game_state + and "cards" in expected_game_state["hand"] + ): + for card in expected_game_state["hand"]["cards"]: + card.pop("highlighted", None) + + # Assert game state equality assert actual_game_state == expected_game_state, ( f"Game state mismatch at step {step_num + 1} in {jsonl_file.name}\n" f"Function: {function_call['name']}({function_call['arguments']})\n" diff --git a/tests/runs/one_ante_no_shop_1.jsonl b/tests/runs/one_ante_no_shop_1.jsonl index a12852b..7ccee54 100644 --- a/tests/runs/one_ante_no_shop_1.jsonl +++ b/tests/runs/one_ante_no_shop_1.jsonl @@ -1,17 +1,17 @@ -{"function":{"name":"start_run","arguments":{"deck":"Red Deck","seed":"OOOO155","stake":1}},"timestamp_ms":1752669257783,"game_state":{"state":11,"jokers":[],"game":{"round":0,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":0,"current_round":{"hands_left":0,"discards_left":0},"chips":0,"dollars":0,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"select"}},"timestamp_ms":1752669258636,"game_state":{"state":7,"jokers":[],"hand":[],"game":{"round":0,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":0,"blind_on_deck":"Small","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":4,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[0,1,2,3]}},"timestamp_ms":1752669259341,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Jack","suit":"Spades","name":"Jack of Spades","card_key":"S_J"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Hearts","name":"Jack of Hearts","card_key":"H_J"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Clubs","name":"Jack of Clubs","card_key":"C_J"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Diamonds","name":"Jack of Diamonds","card_key":"D_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Hearts","name":"10 of Hearts","card_key":"H_T"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"9","suit":"Clubs","name":"9 of Clubs","card_key":"C_9"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Diamonds","name":"7 of Diamonds","card_key":"D_7"}},"label":"Base Card"}],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":0,"blind_on_deck":"Small","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":4,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"cash_out","arguments":[]},"timestamp_ms":1752669262384,"game_state":{"state":8,"jokers":[],"hand":[],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":0,"blind_on_deck":"Small","current_round":{"hands_left":3,"discards_left":4},"chips":700,"dollars":4,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"shop","arguments":{"action":"next_round"}},"timestamp_ms":1752669262814,"game_state":{"state":5,"jokers":[],"hand":[],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":0,"blind_on_deck":"Small","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":10,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"skip"}},"timestamp_ms":1752669263003,"game_state":{"state":7,"jokers":[],"hand":[],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":0,"blind_on_deck":"Big","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":10,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"select"}},"timestamp_ms":1752669263296,"game_state":{"state":7,"jokers":[],"hand":[],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":20,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[2,3,5,6]}},"timestamp_ms":1752669263984,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"King","suit":"Spades","name":"King of Spades","card_key":"S_K"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Hearts","name":"King of Hearts","card_key":"H_K"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Diamonds","name":"Jack of Diamonds","card_key":"D_J"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Clubs","name":"7 of Clubs","card_key":"C_7"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Clubs","name":"5 of Clubs","card_key":"C_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Spades","name":"4 of Spades","card_key":"S_4"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Diamonds","name":"3 of Diamonds","card_key":"D_3"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":20,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[2,3,6]}},"timestamp_ms":1752669264480,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"King","suit":"Spades","name":"King of Spades","card_key":"S_K"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Hearts","name":"King of Hearts","card_key":"H_K"}},"label":"Base Card"},{"config":{"card":{"value":"9","suit":"Diamonds","name":"9 of Diamonds","card_key":"D_9"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Clubs","name":"8 of Clubs","card_key":"C_8"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Clubs","name":"5 of Clubs","card_key":"C_5"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Diamonds","name":"2 of Diamonds","card_key":"D_2"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":3},"chips":0,"dollars":20,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[3,5,6]}},"timestamp_ms":1752669264890,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Ace","suit":"Hearts","name":"Ace of Hearts","card_key":"H_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Spades","name":"King of Spades","card_key":"S_K"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Hearts","name":"King of Hearts","card_key":"H_K"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Spades","name":"8 of Spades","card_key":"S_8"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Clubs","name":"5 of Clubs","card_key":"C_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Clubs","name":"4 of Clubs","card_key":"C_4"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":2},"chips":0,"dollars":20,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[3,4,6]}},"timestamp_ms":1752669265299,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Ace","suit":"Hearts","name":"Ace of Hearts","card_key":"H_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Spades","name":"King of Spades","card_key":"S_K"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Hearts","name":"King of Hearts","card_key":"H_K"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Spades","name":"10 of Spades","card_key":"S_T"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Spades","name":"5 of Spades","card_key":"S_5"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Diamonds","name":"4 of Diamonds","card_key":"D_4"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":1},"chips":0,"dollars":20,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[1,2,3,4]}},"timestamp_ms":1752669265713,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Ace","suit":"Hearts","name":"Ace of Hearts","card_key":"H_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Spades","name":"King of Spades","card_key":"S_K"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Hearts","name":"King of Hearts","card_key":"H_K"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Clubs","name":"King of Clubs","card_key":"C_K"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Spades","name":"7 of Spades","card_key":"S_7"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Hearts","name":"6 of Hearts","card_key":"H_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":0},"chips":0,"dollars":20,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[0,1,6]}},"timestamp_ms":1752669267410,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Ace","suit":"Hearts","name":"Ace of Hearts","card_key":"H_A"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Hearts","name":"6 of Hearts","card_key":"H_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Hearts","name":"4 of Hearts","card_key":"H_4"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Hearts","name":"3 of Hearts","card_key":"H_3"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Clubs","name":"2 of Clubs","card_key":"C_2"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":3,"discards_left":0},"chips":180,"dollars":20,"hands_played":2,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[2,3,4,5,6]}},"timestamp_ms":1752669268730,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Queen","suit":"Spades","name":"Queen of Spades","card_key":"S_Q"}},"label":"Base Card"},{"config":{"card":{"value":"Queen","suit":"Clubs","name":"Queen of Clubs","card_key":"C_Q"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Hearts","name":"6 of Hearts","card_key":"H_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Hearts","name":"4 of Hearts","card_key":"H_4"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Hearts","name":"3 of Hearts","card_key":"H_3"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":2,"discards_left":0},"chips":196,"dollars":20,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"cash_out","arguments":[]},"timestamp_ms":1752669272912,"game_state":{"state":8,"jokers":[],"hand":[],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Boss","current_round":{"hands_left":1,"discards_left":0},"chips":1196,"dollars":20,"hands_played":4,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"shop","arguments":{"action":"next_round"}},"timestamp_ms":1752669273322,"game_state":{"state":5,"jokers":[],"hand":[],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Small","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":30,"hands_played":4,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"go_to_menu","arguments":[]},"timestamp_ms":1752669273511,"game_state":{"state":7,"jokers":[],"hand":[],"game":{"round":2,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Small","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":30,"hands_played":4,"discount_percent":0,"interest_cap":25}}} +{"function":{"arguments":{"deck":"Red Deck","seed":"OOOO155","stake":1},"name":"start_run"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":3,"voucher":[],"hands_played":1},"skips":0,"bosses_used":[],"unused_discards":0,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":false,"name":"Small Blind"},"chips":12,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_J","card":{"suit":"Spades","value":"Jack","name":"Jack of Spades"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Spades","original_value":"Jack","name":"Jack of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_J","card":{"suit":"Hearts","value":"Jack","name":"Jack of Hearts"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Hearts","original_value":"Jack","name":"Jack of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_J","card":{"suit":"Clubs","value":"Jack","name":"Jack of Clubs"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Clubs","original_value":"Jack","name":"Jack of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_T","card":{"suit":"Hearts","value":"10","name":"10 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Hearts","original_value":"10","name":"10 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_9","card":{"suit":"Clubs","value":"9","name":"9 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Clubs","original_value":"9","name":"9 of Clubs"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103989560} +{"function":{"arguments":{"action":"select"},"name":"skip_or_select_blind"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":0,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":0,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103990417} +{"function":{"arguments":{"action":"play_hand","cards":[0,1,2,3]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":0,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":false,"name":"Small Blind"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_J","card":{"suit":"Spades","value":"Jack","name":"Jack of Spades"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Spades","original_value":"Jack","name":"Jack of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_J","card":{"suit":"Hearts","value":"Jack","name":"Jack of Hearts"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Hearts","original_value":"Jack","name":"Jack of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_J","card":{"suit":"Clubs","value":"Jack","name":"Jack of Clubs"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Clubs","original_value":"Jack","name":"Jack of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_T","card":{"suit":"Hearts","value":"10","name":"10 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Hearts","original_value":"10","name":"10 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_9","card":{"suit":"Clubs","value":"9","name":"9 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Clubs","original_value":"9","name":"9 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_7","card":{"suit":"Diamonds","value":"7","name":"7 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Diamonds","original_value":"7","name":"7 of Diamonds"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103991116} +{"function":{"arguments":[],"name":"cash_out"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":3,"voucher":[],"hands_played":1},"skips":0,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":700,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":8},"timestamp_ms":1753103994152} +{"function":{"arguments":{"action":"next_round"},"name":"shop"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":1},"skips":0,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":5},"timestamp_ms":1753103994575} +{"function":{"arguments":{"action":"skip"},"name":"skip_or_select_blind"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":1},"skips":0,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103994763} +{"function":{"arguments":{"action":"select"},"name":"skip_or_select_blind"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":1},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103995053} +{"function":{"arguments":{"action":"discard","cards":[2,3,5,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Manacle"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_K","card":{"suit":"Spades","value":"King","name":"King of Spades"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Spades","original_value":"King","name":"King of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_K","card":{"suit":"Hearts","value":"King","name":"King of Hearts"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Hearts","original_value":"King","name":"King of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":1,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_7","card":{"suit":"Clubs","value":"7","name":"7 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Clubs","original_value":"7","name":"7 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_5","card":{"suit":"Clubs","value":"5","name":"5 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Clubs","original_value":"5","name":"5 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_4","card":{"suit":"Spades","value":"4","name":"4 of Spades"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Spades","original_value":"4","name":"4 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_3","card":{"suit":"Diamonds","value":"3","name":"3 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Diamonds","original_value":"3","name":"3 of Diamonds"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":7,"card_count":7}},"state":1},"timestamp_ms":1753103995730} +{"function":{"arguments":{"action":"discard","cards":[2,3,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":3,"discards_used":1,"hands_left":4,"voucher":[],"hands_played":0},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Manacle"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_K","card":{"suit":"Spades","value":"King","name":"King of Spades"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Spades","original_value":"King","name":"King of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_K","card":{"suit":"Hearts","value":"King","name":"King of Hearts"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Hearts","original_value":"King","name":"King of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_9","card":{"suit":"Diamonds","value":"9","name":"9 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Diamonds","original_value":"9","name":"9 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_8","card":{"suit":"Clubs","value":"8","name":"8 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Clubs","original_value":"8","name":"8 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_5","card":{"suit":"Clubs","value":"5","name":"5 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Clubs","original_value":"5","name":"5 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_2","card":{"suit":"Diamonds","value":"2","name":"2 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":0,"nominal":2,"value":"2","suit":"Diamonds","original_value":"2","name":"2 of Diamonds"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":7,"card_count":7}},"state":1},"timestamp_ms":1753103996228} +{"function":{"arguments":{"action":"discard","cards":[3,5,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":2,"discards_used":2,"hands_left":4,"voucher":[],"hands_played":0},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Manacle"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_K","card":{"suit":"Spades","value":"King","name":"King of Spades"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Spades","original_value":"King","name":"King of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_K","card":{"suit":"Hearts","value":"King","name":"King of Hearts"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Hearts","original_value":"King","name":"King of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_8","card":{"suit":"Spades","value":"8","name":"8 of Spades"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Spades","original_value":"8","name":"8 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_5","card":{"suit":"Clubs","value":"5","name":"5 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Clubs","original_value":"5","name":"5 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_4","card":{"suit":"Clubs","value":"4","name":"4 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Clubs","original_value":"4","name":"4 of Clubs"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":7,"card_count":7}},"state":1},"timestamp_ms":1753103996630} +{"function":{"arguments":{"action":"discard","cards":[3,4,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":4,"voucher":[],"hands_played":0},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Manacle"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_K","card":{"suit":"Spades","value":"King","name":"King of Spades"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Spades","original_value":"King","name":"King of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_K","card":{"suit":"Hearts","value":"King","name":"King of Hearts"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Hearts","original_value":"King","name":"King of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_T","card":{"suit":"Spades","value":"10","name":"10 of Spades"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Spades","original_value":"10","name":"10 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_5","card":{"suit":"Spades","value":"5","name":"5 of Spades"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Spades","original_value":"5","name":"5 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_4","card":{"suit":"Diamonds","value":"4","name":"4 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Diamonds","original_value":"4","name":"4 of Diamonds"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":7,"card_count":7}},"state":1},"timestamp_ms":1753103997043} +{"function":{"arguments":{"action":"play_hand","cards":[1,2,3,4]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":0,"discards_used":4,"hands_left":4,"voucher":[],"hands_played":0},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":1,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Manacle"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_K","card":{"suit":"Spades","value":"King","name":"King of Spades"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Spades","original_value":"King","name":"King of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_K","card":{"suit":"Hearts","value":"King","name":"King of Hearts"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Hearts","original_value":"King","name":"King of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_K","card":{"suit":"Clubs","value":"King","name":"King of Clubs"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Clubs","original_value":"King","name":"King of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_7","card":{"suit":"Spades","value":"7","name":"7 of Spades"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Spades","original_value":"7","name":"7 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_6","card":{"suit":"Hearts","value":"6","name":"6 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":0,"nominal":6,"value":"6","suit":"Hearts","original_value":"6","name":"6 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":7,"card_count":7}},"state":1},"timestamp_ms":1753103997447} +{"function":{"arguments":{"action":"play_hand","cards":[0,1,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":0,"discards_used":4,"hands_left":3,"voucher":[],"hands_played":1},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":2,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Manacle"},"chips":180,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_6","card":{"suit":"Hearts","value":"6","name":"6 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":0,"nominal":6,"value":"6","suit":"Hearts","original_value":"6","name":"6 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_4","card":{"suit":"Hearts","value":"4","name":"4 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Hearts","original_value":"4","name":"4 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_3","card":{"suit":"Hearts","value":"3","name":"3 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Hearts","original_value":"3","name":"3 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_2","card":{"suit":"Clubs","value":"2","name":"2 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":0,"nominal":2,"value":"2","suit":"Clubs","original_value":"2","name":"2 of Clubs"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":7,"card_count":7}},"state":1},"timestamp_ms":1753103999118} +{"function":{"arguments":{"action":"play_hand","cards":[2,3,4,5,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":0,"discards_used":4,"hands_left":2,"voucher":[],"hands_played":2},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":3,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Manacle"},"chips":196,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_Q","card":{"suit":"Spades","value":"Queen","name":"Queen of Spades"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Spades","original_value":"Queen","name":"Queen of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_Q","card":{"suit":"Clubs","value":"Queen","name":"Queen of Clubs"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Clubs","original_value":"Queen","name":"Queen of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_6","card":{"suit":"Hearts","value":"6","name":"6 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":0,"nominal":6,"value":"6","suit":"Hearts","original_value":"6","name":"6 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_4","card":{"suit":"Hearts","value":"4","name":"4 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Hearts","original_value":"4","name":"4 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_3","card":{"suit":"Hearts","value":"3","name":"3 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Hearts","original_value":"3","name":"3 of Hearts"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":7,"card_count":7}},"state":1},"timestamp_ms":1753104000433} +{"function":{"arguments":[],"name":"cash_out"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":20,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":0,"discards_used":4,"hands_left":1,"voucher":[],"hands_played":3},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":4,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":1196,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":8},"timestamp_ms":1753104004595} +{"function":{"arguments":{"action":"next_round"},"name":"shop"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":30,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":4,"hands_left":4,"voucher":[],"hands_played":3},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":4,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":5},"timestamp_ms":1753104005002} +{"function":{"arguments":[],"name":"go_to_menu"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":30,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":4,"hands_left":4,"voucher":[],"hands_played":3},"skips":1,"bosses_used":[],"unused_discards":4,"hands_played":4,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753104005189} diff --git a/tests/runs/one_ante_no_shop_2.jsonl b/tests/runs/one_ante_no_shop_2.jsonl index c40b71d..e1a5621 100644 --- a/tests/runs/one_ante_no_shop_2.jsonl +++ b/tests/runs/one_ante_no_shop_2.jsonl @@ -1,31 +1,31 @@ -{"function":{"name":"start_run","arguments":{"deck":"Red Deck","seed":"OOOOOOO","stake":1}},"timestamp_ms":1752669312830,"game_state":{"state":11,"jokers":[],"game":{"round":0,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":0,"current_round":{"hands_left":0,"discards_left":0},"chips":0,"dollars":0,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"skip"}},"timestamp_ms":1752669313694,"game_state":{"state":7,"jokers":[],"hand":[],"game":{"round":0,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":0,"blind_on_deck":"Small","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":4,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"skip"}},"timestamp_ms":1752669313815,"game_state":{"state":7,"jokers":[],"hand":[],"game":{"round":0,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":1,"blind_on_deck":"Big","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":4,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"select"}},"timestamp_ms":1752669313935,"game_state":{"state":7,"jokers":[],"hand":[],"game":{"round":0,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":4,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[1,5,6,7]}},"timestamp_ms":1752669314638,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Ace","suit":"Diamonds","name":"Ace of Diamonds","card_key":"D_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Hearts","name":"King of Hearts","card_key":"H_K"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Clubs","name":"King of Clubs","card_key":"C_K"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Spades","name":"Jack of Spades","card_key":"S_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"9","suit":"Diamonds","name":"9 of Diamonds","card_key":"D_9"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Spades","name":"7 of Spades","card_key":"S_7"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Hearts","name":"3 of Hearts","card_key":"H_3"}},"label":"Base Card"}],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":4,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[0,2,5,6]}},"timestamp_ms":1752669315135,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Ace","suit":"Diamonds","name":"Ace of Diamonds","card_key":"D_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Clubs","name":"King of Clubs","card_key":"C_K"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Spades","name":"Jack of Spades","card_key":"S_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Clubs","name":"8 of Clubs","card_key":"C_8"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Diamonds","name":"8 of Diamonds","card_key":"D_8"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Diamonds","name":"4 of Diamonds","card_key":"D_4"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Clubs","name":"2 of Clubs","card_key":"C_2"}},"label":"Base Card"}],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":3},"chips":0,"dollars":4,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[0,3,4,6,7]}},"timestamp_ms":1752669315612,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"King","suit":"Clubs","name":"King of Clubs","card_key":"C_K"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"9","suit":"Spades","name":"9 of Spades","card_key":"S_9"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Clubs","name":"8 of Clubs","card_key":"C_8"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Clubs","name":"6 of Clubs","card_key":"C_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Spades","name":"5 of Spades","card_key":"S_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Clubs","name":"4 of Clubs","card_key":"C_4"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Clubs","name":"2 of Clubs","card_key":"C_2"}},"label":"Base Card"}],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":2},"chips":0,"dollars":4,"hands_played":0,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[0,3,4,5,6]}},"timestamp_ms":1752669317688,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Jack","suit":"Hearts","name":"Jack of Hearts","card_key":"H_J"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Clubs","name":"Jack of Clubs","card_key":"C_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"9","suit":"Spades","name":"9 of Spades","card_key":"S_9"}},"label":"Base Card"},{"config":{"card":{"value":"9","suit":"Hearts","name":"9 of Hearts","card_key":"H_9"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Spades","name":"5 of Spades","card_key":"S_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Spades","name":"4 of Spades","card_key":"S_4"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Clubs","name":"3 of Clubs","card_key":"C_3"}},"label":"Base Card"}],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":3,"discards_left":2},"chips":260,"dollars":4,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[0,1,3,5,7]}},"timestamp_ms":1752669318235,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Ace","suit":"Hearts","name":"Ace of Hearts","card_key":"H_A"}},"label":"Base Card"},{"config":{"card":{"value":"Queen","suit":"Hearts","name":"Queen of Hearts","card_key":"H_Q"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Clubs","name":"Jack of Clubs","card_key":"C_J"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Diamonds","name":"Jack of Diamonds","card_key":"D_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Diamonds","name":"5 of Diamonds","card_key":"D_5"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Clubs","name":"3 of Clubs","card_key":"C_3"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Spades","name":"2 of Spades","card_key":"S_2"}},"label":"Base Card"}],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":3,"discards_left":1},"chips":260,"dollars":4,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[1,2,3,4,5]}},"timestamp_ms":1752669318787,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Jack","suit":"Clubs","name":"Jack of Clubs","card_key":"C_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Spades","name":"10 of Spades","card_key":"S_T"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Diamonds","name":"10 of Diamonds","card_key":"D_T"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Spades","name":"6 of Spades","card_key":"S_6"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Diamonds","name":"6 of Diamonds","card_key":"D_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Clubs","name":"5 of Clubs","card_key":"C_5"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Clubs","name":"3 of Clubs","card_key":"C_3"}},"label":"Base Card"}],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":3,"discards_left":0},"chips":260,"dollars":4,"hands_played":1,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[0,2,4,5,7]}},"timestamp_ms":1752669320856,"game_state":{"state":1,"jokers":[],"hand":[{"config":{"card":{"value":"Ace","suit":"Clubs","name":"Ace of Clubs","card_key":"C_A"}},"label":"Base Card"},{"config":{"card":{"value":"Queen","suit":"Spades","name":"Queen of Spades","card_key":"S_Q"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Clubs","name":"Jack of Clubs","card_key":"C_J"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Spades","name":"8 of Spades","card_key":"S_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Clubs","name":"7 of Clubs","card_key":"C_7"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Clubs","name":"5 of Clubs","card_key":"C_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Hearts","name":"4 of Hearts","card_key":"H_4"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Clubs","name":"3 of Clubs","card_key":"C_3"}},"label":"Base Card"}],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":2,"discards_left":0},"chips":588,"dollars":4,"hands_played":2,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"cash_out","arguments":[]},"timestamp_ms":1752669325154,"game_state":{"state":8,"jokers":[],"hand":[],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Boss","current_round":{"hands_left":1,"discards_left":0},"chips":872,"dollars":4,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"shop","arguments":{"action":"next_round"}},"timestamp_ms":1752669325702,"game_state":{"state":5,"jokers":[],"hand":[],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Small","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":10,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"skip"}},"timestamp_ms":1752669325891,"game_state":{"state":7,"jokers":[],"hand":[],"game":{"round":1,"inflation":0,"max_jokers":0,"bankrupt_at":0,"skips":2,"blind_on_deck":"Small","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":10,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"select"}},"timestamp_ms":1752669326167,"game_state":{"state":7,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[],"game":{"round":1,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Big","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":10,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[2,4,6,7]}},"timestamp_ms":1752669326874,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"King","suit":"Diamonds","name":"King of Diamonds","card_key":"D_K"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Diamonds","name":"Jack of Diamonds","card_key":"D_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Hearts","name":"10 of Hearts","card_key":"H_T"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Diamonds","name":"10 of Diamonds","card_key":"D_T"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Spades","name":"8 of Spades","card_key":"S_8"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Diamonds","name":"8 of Diamonds","card_key":"D_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Spades","name":"7 of Spades","card_key":"S_7"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Clubs","name":"5 of Clubs","card_key":"C_5"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Big","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":10,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[5,6,7]}},"timestamp_ms":1752669327352,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"Ace","suit":"Spades","name":"Ace of Spades","card_key":"S_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Diamonds","name":"King of Diamonds","card_key":"D_K"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Diamonds","name":"Jack of Diamonds","card_key":"D_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Diamonds","name":"10 of Diamonds","card_key":"D_T"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Diamonds","name":"8 of Diamonds","card_key":"D_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Clubs","name":"4 of Clubs","card_key":"C_4"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Hearts","name":"3 of Hearts","card_key":"H_3"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Big","current_round":{"hands_left":4,"discards_left":3},"chips":0,"dollars":10,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[0,1,4,7]}},"timestamp_ms":1752669327762,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"Ace","suit":"Spades","name":"Ace of Spades","card_key":"S_A"}},"label":"Base Card"},{"config":{"card":{"value":"Ace","suit":"Clubs","name":"Ace of Clubs","card_key":"C_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Diamonds","name":"King of Diamonds","card_key":"D_K"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Diamonds","name":"Jack of Diamonds","card_key":"D_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Spades","name":"10 of Spades","card_key":"S_T"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Diamonds","name":"10 of Diamonds","card_key":"D_T"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Diamonds","name":"8 of Diamonds","card_key":"D_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Clubs","name":"7 of Clubs","card_key":"C_7"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Big","current_round":{"hands_left":4,"discards_left":2},"chips":0,"dollars":10,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[0,2,3,4,5]}},"timestamp_ms":1752669328242,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"King","suit":"Diamonds","name":"King of Diamonds","card_key":"D_K"}},"label":"Base Card"},{"config":{"card":{"value":"Queen","suit":"Hearts","name":"Queen of Hearts","card_key":"H_Q"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Diamonds","name":"Jack of Diamonds","card_key":"D_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Diamonds","name":"10 of Diamonds","card_key":"D_T"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Diamonds","name":"8 of Diamonds","card_key":"D_8"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Diamonds","name":"6 of Diamonds","card_key":"D_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Clubs","name":"2 of Clubs","card_key":"C_2"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Big","current_round":{"hands_left":4,"discards_left":1},"chips":0,"dollars":10,"hands_played":3,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[0,1,4,5]}},"timestamp_ms":1752669330437,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"King","suit":"Spades","name":"King of Spades","card_key":"S_K"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Hearts","name":"King of Hearts","card_key":"H_K"}},"label":"Base Card"},{"config":{"card":{"value":"Queen","suit":"Spades","name":"Queen of Spades","card_key":"S_Q"}},"label":"Base Card"},{"config":{"card":{"value":"Queen","suit":"Hearts","name":"Queen of Hearts","card_key":"H_Q"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Spades","name":"Jack of Spades","card_key":"S_J"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Clubs","name":"Jack of Clubs","card_key":"C_J"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Clubs","name":"2 of Clubs","card_key":"C_2"}},"label":"Base Card"}],"game":{"round":2,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Big","current_round":{"hands_left":3,"discards_left":1},"chips":632,"dollars":10,"hands_played":4,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"cash_out","arguments":[]},"timestamp_ms":1752669334374,"game_state":{"state":8,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[],"game":{"round":2,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Big","current_round":{"hands_left":2,"discards_left":1},"chips":1352,"dollars":10,"hands_played":5,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"shop","arguments":{"action":"next_round"}},"timestamp_ms":1752669334923,"game_state":{"state":5,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[],"game":{"round":2,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Big","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":18,"hands_played":5,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"skip_or_select_blind","arguments":{"action":"select"}},"timestamp_ms":1752669335113,"game_state":{"state":7,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[],"game":{"round":2,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":18,"hands_played":5,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[0,1,2,3,6]}},"timestamp_ms":1752669335826,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"Jack","suit":"Spades","name":"Jack of Spades","card_key":"S_J"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Spades","name":"10 of Spades","card_key":"S_T"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Diamonds","name":"10 of Diamonds","card_key":"D_T"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Clubs","name":"8 of Clubs","card_key":"C_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Clubs","name":"5 of Clubs","card_key":"C_5"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Hearts","name":"3 of Hearts","card_key":"H_3"}},"label":"Base Card"}],"game":{"round":3,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":4},"chips":0,"dollars":18,"hands_played":5,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[4,5,6,7]}},"timestamp_ms":1752669336391,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"Queen","suit":"Diamonds","name":"Queen of Diamonds","card_key":"D_Q"}},"label":"Base Card"},{"config":{"card":{"value":"9","suit":"Spades","name":"9 of Spades","card_key":"S_9"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Hearts","name":"3 of Hearts","card_key":"H_3"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Clubs","name":"3 of Clubs","card_key":"C_3"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Spades","name":"2 of Spades","card_key":"S_2"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Clubs","name":"2 of Clubs","card_key":"C_2"}},"label":"Base Card"}],"game":{"round":3,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":4,"discards_left":3},"chips":0,"dollars":18,"hands_played":5,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[1,2,3,4,7]}},"timestamp_ms":1752669338317,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"Ace","suit":"Hearts","name":"Ace of Hearts","card_key":"H_A"}},"label":"Base Card"},{"config":{"card":{"value":"Ace","suit":"Diamonds","name":"Ace of Diamonds","card_key":"D_A"}},"label":"Base Card"},{"config":{"card":{"value":"Queen","suit":"Diamonds","name":"Queen of Diamonds","card_key":"D_Q"}},"label":"Base Card"},{"config":{"card":{"value":"10","suit":"Clubs","name":"10 of Clubs","card_key":"C_T"}},"label":"Base Card"},{"config":{"card":{"value":"9","suit":"Spades","name":"9 of Spades","card_key":"S_9"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Diamonds","name":"4 of Diamonds","card_key":"D_4"}},"label":"Base Card"}],"game":{"round":3,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":3,"discards_left":3},"chips":250,"dollars":18,"hands_played":6,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"discard","cards":[2,3,7]}},"timestamp_ms":1752669338867,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"Ace","suit":"Hearts","name":"Ace of Hearts","card_key":"H_A"}},"label":"Base Card"},{"config":{"card":{"value":"Ace","suit":"Clubs","name":"Ace of Clubs","card_key":"C_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Clubs","name":"King of Clubs","card_key":"C_K"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Spades","name":"8 of Spades","card_key":"S_8"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Hearts","name":"8 of Hearts","card_key":"H_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Spades","name":"3 of Spades","card_key":"S_3"}},"label":"Base Card"}],"game":{"round":3,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":3,"discards_left":2},"chips":250,"dollars":18,"hands_played":6,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[0,1,2,3]}},"timestamp_ms":1752669339277,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"Ace","suit":"Spades","name":"Ace of Spades","card_key":"S_A"}},"label":"Base Card"},{"config":{"card":{"value":"Ace","suit":"Hearts","name":"Ace of Hearts","card_key":"H_A"}},"label":"Base Card"},{"config":{"card":{"value":"Ace","suit":"Clubs","name":"Ace of Clubs","card_key":"C_A"}},"label":"Base Card"},{"config":{"card":{"value":"King","suit":"Spades","name":"King of Spades","card_key":"S_K"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Hearts","name":"8 of Hearts","card_key":"H_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Clubs","name":"6 of Clubs","card_key":"C_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"}],"game":{"round":3,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":3,"discards_left":1},"chips":250,"dollars":18,"hands_played":6,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[0,1,2,7]}},"timestamp_ms":1752669341063,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"Queen","suit":"Spades","name":"Queen of Spades","card_key":"S_Q"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Clubs","name":"Jack of Clubs","card_key":"C_J"}},"label":"Base Card"},{"config":{"card":{"value":"Jack","suit":"Diamonds","name":"Jack of Diamonds","card_key":"D_J"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Hearts","name":"8 of Hearts","card_key":"H_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Clubs","name":"6 of Clubs","card_key":"C_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"2","suit":"Diamonds","name":"2 of Diamonds","card_key":"D_2"}},"label":"Base Card"}],"game":{"round":3,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":2,"discards_left":1},"chips":822,"dollars":18,"hands_played":7,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"play_hand_or_discard","arguments":{"action":"play_hand","cards":[1,3,4,5,6]}},"timestamp_ms":1752669342835,"game_state":{"state":1,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"10","suit":"Hearts","name":"10 of Hearts","card_key":"H_T"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Hearts","name":"8 of Hearts","card_key":"H_8"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Diamonds","name":"8 of Diamonds","card_key":"D_8"}},"label":"Base Card"},{"config":{"card":{"value":"7","suit":"Hearts","name":"7 of Hearts","card_key":"H_7"}},"label":"Base Card"},{"config":{"card":{"value":"6","suit":"Clubs","name":"6 of Clubs","card_key":"C_6"}},"label":"Base Card"},{"config":{"card":{"value":"5","suit":"Hearts","name":"5 of Hearts","card_key":"H_5"}},"label":"Base Card"},{"config":{"card":{"value":"4","suit":"Clubs","name":"4 of Clubs","card_key":"C_4"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Diamonds","name":"3 of Diamonds","card_key":"D_3"}},"label":"Base Card"}],"game":{"round":3,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":1,"discards_left":1},"chips":1062,"dollars":18,"hands_played":8,"discount_percent":0,"interest_cap":25}}} -{"function":{"name":"go_to_menu","arguments":[]},"timestamp_ms":1752669345526,"game_state":{"state":4,"jokers":[{"config":{"center":{"blueprint_compat":true,"_d":false,"eternal_compat":true,"order":6,"key":"j_jolly","alerted":true,"unlocked":true,"discovered":true,"cost_mult":1,"_discovered_unlocked_overwritten":true,"_u":true,"cost":3,"_saved_d_u":true,"config":{"type":"Pair","t_mult":8},"pos":{"x":2,"y":0},"name":"Jolly Joker","set":"Joker","rarity":1,"effect":"Type Mult","perishable_compat":true}},"label":"Jolly Joker"},{"config":{"center":{"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"key":"j_photograph","rarity":1,"_saved_d_u":true,"name":"Photograph","config":{"extra":2},"pos":{"x":2,"y":13},"set":"Joker","_u":true,"_d":false,"_discovered_unlocked_overwritten":true,"cost":5}},"label":"Photograph"}],"hand":[{"config":{"card":{"value":"10","suit":"Hearts","name":"10 of Hearts","card_key":"H_T"}},"label":"Base Card"},{"config":{"card":{"value":"8","suit":"Diamonds","name":"8 of Diamonds","card_key":"D_8"}},"label":"Base Card"},{"config":{"card":{"value":"3","suit":"Diamonds","name":"3 of Diamonds","card_key":"D_3"}},"label":"Base Card"}],"game":{"round":3,"inflation":0,"max_jokers":2,"bankrupt_at":0,"skips":3,"blind_on_deck":"Boss","current_round":{"hands_left":0,"discards_left":1},"chips":1262,"dollars":18,"hands_played":9,"discount_percent":0,"interest_cap":25}}} +{"function":{"arguments":{"deck":"Red Deck","seed":"OOOOOOO","stake":1},"name":"start_run"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":0,"shop":[],"round":0,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":0,"discards_used":0,"hands_left":0,"voucher":[],"hands_played":0},"skips":0,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"tags":[],"smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":false,"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"state":11},"timestamp_ms":1753103170838} +{"function":{"arguments":{"action":"skip"},"name":"skip_or_select_blind"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":0,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":0,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103171671} +{"function":{"arguments":{"action":"skip"},"name":"skip_or_select_blind"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":0,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":1,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103171789} +{"function":{"arguments":{"action":"select"},"name":"skip_or_select_blind"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":0,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103171904} +{"function":{"arguments":{"action":"discard","cards":[1,5,6,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Head"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"D_A","card":{"suit":"Diamonds","value":"Ace","name":"Ace of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Diamonds","original_value":"Ace","name":"Ace of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_K","card":{"suit":"Hearts","value":"King","name":"King of Hearts"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Hearts","original_value":"King","name":"King of Hearts"},"highlighted":true,"debuff":true},{"config":{"card_key":"C_K","card":{"suit":"Clubs","value":"King","name":"King of Clubs"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Clubs","original_value":"King","name":"King of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_J","card":{"suit":"Spades","value":"Jack","name":"Jack of Spades"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Spades","original_value":"Jack","name":"Jack of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_9","card":{"suit":"Diamonds","value":"9","name":"9 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Diamonds","original_value":"9","name":"9 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_7","card":{"suit":"Spades","value":"7","name":"7 of Spades"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Spades","original_value":"7","name":"7 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_3","card":{"suit":"Hearts","value":"3","name":"3 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Hearts","original_value":"3","name":"3 of Hearts"},"highlighted":true,"debuff":true}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103172597} +{"function":{"arguments":{"action":"discard","cards":[0,2,5,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":3,"discards_used":1,"hands_left":4,"voucher":[],"hands_played":0},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Head"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"D_A","card":{"suit":"Diamonds","value":"Ace","name":"Ace of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Diamonds","original_value":"Ace","name":"Ace of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_K","card":{"suit":"Clubs","value":"King","name":"King of Clubs"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Clubs","original_value":"King","name":"King of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_J","card":{"suit":"Spades","value":"Jack","name":"Jack of Spades"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Spades","original_value":"Jack","name":"Jack of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_8","card":{"suit":"Clubs","value":"8","name":"8 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Clubs","original_value":"8","name":"8 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_8","card":{"suit":"Diamonds","value":"8","name":"8 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Diamonds","original_value":"8","name":"8 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_4","card":{"suit":"Diamonds","value":"4","name":"4 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Diamonds","original_value":"4","name":"4 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_2","card":{"suit":"Clubs","value":"2","name":"2 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":0,"nominal":2,"value":"2","suit":"Clubs","original_value":"2","name":"2 of Clubs"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103173091} +{"function":{"arguments":{"action":"play_hand","cards":[0,3,4,6,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":2,"discards_used":2,"hands_left":4,"voucher":[],"hands_played":0},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":0,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Head"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"C_K","card":{"suit":"Clubs","value":"King","name":"King of Clubs"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Clubs","original_value":"King","name":"King of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_9","card":{"suit":"Spades","value":"9","name":"9 of Spades"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Spades","original_value":"9","name":"9 of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_8","card":{"suit":"Clubs","value":"8","name":"8 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Clubs","original_value":"8","name":"8 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_6","card":{"suit":"Clubs","value":"6","name":"6 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":0,"nominal":6,"value":"6","suit":"Clubs","original_value":"6","name":"6 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_5","card":{"suit":"Spades","value":"5","name":"5 of Spades"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Spades","original_value":"5","name":"5 of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_4","card":{"suit":"Clubs","value":"4","name":"4 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Clubs","original_value":"4","name":"4 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_2","card":{"suit":"Clubs","value":"2","name":"2 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":0,"nominal":2,"value":"2","suit":"Clubs","original_value":"2","name":"2 of Clubs"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103173567} +{"function":{"arguments":{"action":"discard","cards":[0,3,4,5,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":2,"discards_used":2,"hands_left":3,"voucher":[],"hands_played":1},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":1,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Head"},"chips":260,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_J","card":{"suit":"Hearts","value":"Jack","name":"Jack of Hearts"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Hearts","original_value":"Jack","name":"Jack of Hearts"},"highlighted":true,"debuff":true},{"config":{"card_key":"C_J","card":{"suit":"Clubs","value":"Jack","name":"Jack of Clubs"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Clubs","original_value":"Jack","name":"Jack of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_9","card":{"suit":"Spades","value":"9","name":"9 of Spades"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Spades","original_value":"9","name":"9 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_9","card":{"suit":"Hearts","value":"9","name":"9 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Hearts","original_value":"9","name":"9 of Hearts"},"highlighted":true,"debuff":true},{"config":{"card_key":"S_5","card":{"suit":"Spades","value":"5","name":"5 of Spades"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Spades","original_value":"5","name":"5 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_4","card":{"suit":"Spades","value":"4","name":"4 of Spades"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Spades","original_value":"4","name":"4 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_3","card":{"suit":"Clubs","value":"3","name":"3 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Clubs","original_value":"3","name":"3 of Clubs"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103175619} +{"function":{"arguments":{"action":"discard","cards":[0,1,3,5,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":3,"voucher":[],"hands_played":1},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":1,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Head"},"chips":260,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":true,"debuff":true},{"config":{"card_key":"H_Q","card":{"suit":"Hearts","value":"Queen","name":"Queen of Hearts"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Hearts","original_value":"Queen","name":"Queen of Hearts"},"highlighted":true,"debuff":true},{"config":{"card_key":"C_J","card":{"suit":"Clubs","value":"Jack","name":"Jack of Clubs"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Clubs","original_value":"Jack","name":"Jack of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_5","card":{"suit":"Diamonds","value":"5","name":"5 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Diamonds","original_value":"5","name":"5 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_3","card":{"suit":"Clubs","value":"3","name":"3 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Clubs","original_value":"3","name":"3 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_2","card":{"suit":"Spades","value":"2","name":"2 of Spades"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":0,"nominal":2,"value":"2","suit":"Spades","original_value":"2","name":"2 of Spades"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103176163} +{"function":{"arguments":{"action":"play_hand","cards":[1,2,3,4,5]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":0,"discards_used":4,"hands_left":3,"voucher":[],"hands_played":1},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":1,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Head"},"chips":260,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"C_J","card":{"suit":"Clubs","value":"Jack","name":"Jack of Clubs"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Clubs","original_value":"Jack","name":"Jack of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_T","card":{"suit":"Spades","value":"10","name":"10 of Spades"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Spades","original_value":"10","name":"10 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_T","card":{"suit":"Diamonds","value":"10","name":"10 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Diamonds","original_value":"10","name":"10 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_6","card":{"suit":"Spades","value":"6","name":"6 of Spades"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":0,"nominal":6,"value":"6","suit":"Spades","original_value":"6","name":"6 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_6","card":{"suit":"Diamonds","value":"6","name":"6 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":0,"nominal":6,"value":"6","suit":"Diamonds","original_value":"6","name":"6 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_5","card":{"suit":"Clubs","value":"5","name":"5 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Clubs","original_value":"5","name":"5 of Clubs"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_3","card":{"suit":"Clubs","value":"3","name":"3 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Clubs","original_value":"3","name":"3 of Clubs"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103176705} +{"function":{"arguments":{"action":"play_hand","cards":[0,2,4,5,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":0,"discards_used":4,"hands_left":2,"voucher":[],"hands_played":2},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":2,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Head"},"chips":588,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"C_A","card":{"suit":"Clubs","value":"Ace","name":"Ace of Clubs"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Clubs","original_value":"Ace","name":"Ace of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_Q","card":{"suit":"Spades","value":"Queen","name":"Queen of Spades"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Spades","original_value":"Queen","name":"Queen of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_J","card":{"suit":"Clubs","value":"Jack","name":"Jack of Clubs"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Clubs","original_value":"Jack","name":"Jack of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_8","card":{"suit":"Spades","value":"8","name":"8 of Spades"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Spades","original_value":"8","name":"8 of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_7","card":{"suit":"Clubs","value":"7","name":"7 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Clubs","original_value":"7","name":"7 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_5","card":{"suit":"Clubs","value":"5","name":"5 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Clubs","original_value":"5","name":"5 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_4","card":{"suit":"Hearts","value":"4","name":"4 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Hearts","original_value":"4","name":"4 of Hearts"},"highlighted":false,"debuff":true},{"config":{"card_key":"C_3","card":{"suit":"Clubs","value":"3","name":"3 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Clubs","original_value":"3","name":"3 of Clubs"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103178752} +{"function":{"arguments":[],"name":"cash_out"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":4,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":0,"discards_used":4,"hands_left":1,"voucher":[],"hands_played":3},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":3,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"},{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":872,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":8},"timestamp_ms":1753103183005} +{"function":{"arguments":{"action":"next_round"},"name":"shop"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":4,"hands_left":4,"voucher":[],"hands_played":3},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":3,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":5},"timestamp_ms":1753103183546} +{"function":{"arguments":{"action":"skip"},"name":"skip_or_select_blind"},"game_state":{"jokers":[],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":0,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":4,"hands_left":4,"voucher":[],"hands_played":3},"skips":2,"bosses_used":[],"unused_discards":0,"hands_played":3,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Small","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103183741} +{"function":{"arguments":{"action":"select"},"name":"skip_or_select_blind"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":1,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":4,"hands_left":4,"voucher":[],"hands_played":3},"skips":3,"bosses_used":[],"unused_discards":0,"hands_played":3,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103184018} +{"function":{"arguments":{"action":"discard","cards":[2,4,6,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":3,"bosses_used":[],"unused_discards":0,"hands_played":3,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":false,"name":"Big Blind"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"D_K","card":{"suit":"Diamonds","value":"King","name":"King of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Diamonds","original_value":"King","name":"King of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_T","card":{"suit":"Hearts","value":"10","name":"10 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Hearts","original_value":"10","name":"10 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_T","card":{"suit":"Diamonds","value":"10","name":"10 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":1,"nominal":10,"value":"10","suit":"Diamonds","original_value":"10","name":"10 of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_8","card":{"suit":"Spades","value":"8","name":"8 of Spades"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Spades","original_value":"8","name":"8 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_8","card":{"suit":"Diamonds","value":"8","name":"8 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Diamonds","original_value":"8","name":"8 of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_7","card":{"suit":"Spades","value":"7","name":"7 of Spades"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Spades","original_value":"7","name":"7 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_5","card":{"suit":"Clubs","value":"5","name":"5 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":1,"nominal":5,"value":"5","suit":"Clubs","original_value":"5","name":"5 of Clubs"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103184722} +{"function":{"arguments":{"action":"discard","cards":[5,6,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":3,"discards_used":1,"hands_left":4,"voucher":[],"hands_played":0},"skips":3,"bosses_used":[],"unused_discards":0,"hands_played":3,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":false,"name":"Big Blind"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_A","card":{"suit":"Spades","value":"Ace","name":"Ace of Spades"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Spades","original_value":"Ace","name":"Ace of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_K","card":{"suit":"Diamonds","value":"King","name":"King of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Diamonds","original_value":"King","name":"King of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_T","card":{"suit":"Diamonds","value":"10","name":"10 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":1,"nominal":10,"value":"10","suit":"Diamonds","original_value":"10","name":"10 of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_8","card":{"suit":"Diamonds","value":"8","name":"8 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Diamonds","original_value":"8","name":"8 of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_4","card":{"suit":"Clubs","value":"4","name":"4 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":1,"nominal":4,"value":"4","suit":"Clubs","original_value":"4","name":"4 of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_3","card":{"suit":"Hearts","value":"3","name":"3 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Hearts","original_value":"3","name":"3 of Hearts"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103185196} +{"function":{"arguments":{"action":"discard","cards":[0,1,4,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":2,"discards_used":2,"hands_left":4,"voucher":[],"hands_played":0},"skips":3,"bosses_used":[],"unused_discards":0,"hands_played":3,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":false,"name":"Big Blind"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_A","card":{"suit":"Spades","value":"Ace","name":"Ace of Spades"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Spades","original_value":"Ace","name":"Ace of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_A","card":{"suit":"Clubs","value":"Ace","name":"Ace of Clubs"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":1,"nominal":11,"value":"Ace","suit":"Clubs","original_value":"Ace","name":"Ace of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_K","card":{"suit":"Diamonds","value":"King","name":"King of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Diamonds","original_value":"King","name":"King of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_T","card":{"suit":"Spades","value":"10","name":"10 of Spades"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":1,"nominal":10,"value":"10","suit":"Spades","original_value":"10","name":"10 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_T","card":{"suit":"Diamonds","value":"10","name":"10 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":1,"nominal":10,"value":"10","suit":"Diamonds","original_value":"10","name":"10 of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_8","card":{"suit":"Diamonds","value":"8","name":"8 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Diamonds","original_value":"8","name":"8 of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_7","card":{"suit":"Clubs","value":"7","name":"7 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":1,"nominal":7,"value":"7","suit":"Clubs","original_value":"7","name":"7 of Clubs"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103185611} +{"function":{"arguments":{"action":"play_hand","cards":[0,2,3,4,5]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":4,"voucher":[],"hands_played":0},"skips":3,"bosses_used":[],"unused_discards":0,"hands_played":3,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":false,"name":"Big Blind"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"D_K","card":{"suit":"Diamonds","value":"King","name":"King of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Diamonds","original_value":"King","name":"King of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_Q","card":{"suit":"Hearts","value":"Queen","name":"Queen of Hearts"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Hearts","original_value":"Queen","name":"Queen of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_T","card":{"suit":"Diamonds","value":"10","name":"10 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":1,"nominal":10,"value":"10","suit":"Diamonds","original_value":"10","name":"10 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_8","card":{"suit":"Diamonds","value":"8","name":"8 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Diamonds","original_value":"8","name":"8 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_6","card":{"suit":"Diamonds","value":"6","name":"6 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":1,"nominal":6,"value":"6","suit":"Diamonds","original_value":"6","name":"6 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_2","card":{"suit":"Clubs","value":"2","name":"2 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":1,"nominal":2,"value":"2","suit":"Clubs","original_value":"2","name":"2 of Clubs"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103186088} +{"function":{"arguments":{"action":"play_hand","cards":[0,1,4,5]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":3,"voucher":[],"hands_played":1},"skips":3,"bosses_used":[],"unused_discards":0,"hands_played":4,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":false,"name":"Big Blind"},"chips":632,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_K","card":{"suit":"Spades","value":"King","name":"King of Spades"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Spades","original_value":"King","name":"King of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_K","card":{"suit":"Hearts","value":"King","name":"King of Hearts"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":0,"nominal":10,"value":"King","suit":"Hearts","original_value":"King","name":"King of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_Q","card":{"suit":"Spades","value":"Queen","name":"Queen of Spades"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Spades","original_value":"Queen","name":"Queen of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_Q","card":{"suit":"Hearts","value":"Queen","name":"Queen of Hearts"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Hearts","original_value":"Queen","name":"Queen of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_J","card":{"suit":"Spades","value":"Jack","name":"Jack of Spades"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":0,"nominal":10,"value":"Jack","suit":"Spades","original_value":"Jack","name":"Jack of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_J","card":{"suit":"Clubs","value":"Jack","name":"Jack of Clubs"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":1,"nominal":10,"value":"Jack","suit":"Clubs","original_value":"Jack","name":"Jack of Clubs"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_2","card":{"suit":"Clubs","value":"2","name":"2 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":1,"nominal":2,"value":"2","suit":"Clubs","original_value":"2","name":"2 of Clubs"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103188261} +{"function":{"arguments":[],"name":"cash_out"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":10,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":2,"voucher":[],"hands_played":2},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":5,"won":false,"seeded":true,"tags":[{"key":"tag_d_six","name":"D6 Tag"}],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":1352,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":8},"timestamp_ms":1753103192153} +{"function":{"arguments":{"action":"next_round"},"name":"shop"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":3,"hands_left":4,"voucher":[],"hands_played":2},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":5,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Big","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":5},"timestamp_ms":1753103192688} +{"function":{"arguments":{"action":"select"},"name":"skip_or_select_blind"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":2,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":3,"hands_left":4,"voucher":[],"hands_played":2},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":5,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"name":""},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[],"config":{"highlighted_limit":5,"card_limit":8,"card_count":0}},"state":7},"timestamp_ms":1753103192874} +{"function":{"arguments":{"action":"discard","cards":[0,1,2,3,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":3,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":4,"discards_used":0,"hands_left":4,"voucher":[],"hands_played":0},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":5,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Club"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_J","card":{"suit":"Spades","value":"Jack","name":"Jack of Spades"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":1,"nominal":10,"value":"Jack","suit":"Spades","original_value":"Jack","name":"Jack of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"S_T","card":{"suit":"Spades","value":"10","name":"10 of Spades"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":1,"nominal":10,"value":"10","suit":"Spades","original_value":"10","name":"10 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_T","card":{"suit":"Diamonds","value":"10","name":"10 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":2,"nominal":10,"value":"10","suit":"Diamonds","original_value":"10","name":"10 of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_8","card":{"suit":"Clubs","value":"8","name":"8 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":1,"nominal":8,"value":"8","suit":"Clubs","original_value":"8","name":"8 of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_5","card":{"suit":"Clubs","value":"5","name":"5 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":1,"nominal":5,"value":"5","suit":"Clubs","original_value":"5","name":"5 of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"H_3","card":{"suit":"Hearts","value":"3","name":"3 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Hearts","original_value":"3","name":"3 of Hearts"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103193569} +{"function":{"arguments":{"action":"play_hand","cards":[4,5,6,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":3,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":3,"discards_used":1,"hands_left":4,"voucher":[],"hands_played":0},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":5,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Club"},"chips":0,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"D_Q","card":{"suit":"Diamonds","value":"Queen","name":"Queen of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Diamonds","original_value":"Queen","name":"Queen of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_9","card":{"suit":"Spades","value":"9","name":"9 of Spades"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Spades","original_value":"9","name":"9 of Spades"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_3","card":{"suit":"Hearts","value":"3","name":"3 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Hearts","original_value":"3","name":"3 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_3","card":{"suit":"Clubs","value":"3","name":"3 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":1,"nominal":3,"value":"3","suit":"Clubs","original_value":"3","name":"3 of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"S_2","card":{"suit":"Spades","value":"2","name":"2 of Spades"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":0,"nominal":2,"value":"2","suit":"Spades","original_value":"2","name":"2 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_2","card":{"suit":"Clubs","value":"2","name":"2 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":1,"nominal":2,"value":"2","suit":"Clubs","original_value":"2","name":"2 of Clubs"},"highlighted":true,"debuff":true}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103194125} +{"function":{"arguments":{"action":"discard","cards":[1,2,3,4,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":3,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":3,"discards_used":1,"hands_left":3,"voucher":[],"hands_played":1},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":6,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Club"},"chips":250,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_A","card":{"suit":"Diamonds","value":"Ace","name":"Ace of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Diamonds","original_value":"Ace","name":"Ace of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_Q","card":{"suit":"Diamonds","value":"Queen","name":"Queen of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Diamonds","original_value":"Queen","name":"Queen of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_T","card":{"suit":"Clubs","value":"10","name":"10 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":1,"nominal":10,"value":"10","suit":"Clubs","original_value":"10","name":"10 of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"S_9","card":{"suit":"Spades","value":"9","name":"9 of Spades"}},"facing":"front","label":"Base Card","base":{"id":9,"times_played":0,"nominal":9,"value":"9","suit":"Spades","original_value":"9","name":"9 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_4","card":{"suit":"Diamonds","value":"4","name":"4 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":0,"nominal":4,"value":"4","suit":"Diamonds","original_value":"4","name":"4 of Diamonds"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103196024} +{"function":{"arguments":{"action":"discard","cards":[2,3,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":3,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":2,"discards_used":2,"hands_left":3,"voucher":[],"hands_played":1},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":6,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Club"},"chips":250,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_A","card":{"suit":"Clubs","value":"Ace","name":"Ace of Clubs"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":1,"nominal":11,"value":"Ace","suit":"Clubs","original_value":"Ace","name":"Ace of Clubs"},"highlighted":false,"debuff":true},{"config":{"card_key":"C_K","card":{"suit":"Clubs","value":"King","name":"King of Clubs"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":1,"nominal":10,"value":"King","suit":"Clubs","original_value":"King","name":"King of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"S_8","card":{"suit":"Spades","value":"8","name":"8 of Spades"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Spades","original_value":"8","name":"8 of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_8","card":{"suit":"Hearts","value":"8","name":"8 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Hearts","original_value":"8","name":"8 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"S_3","card":{"suit":"Spades","value":"3","name":"3 of Spades"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Spades","original_value":"3","name":"3 of Spades"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103196570} +{"function":{"arguments":{"action":"play_hand","cards":[0,1,2,3]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":3,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":3,"voucher":[],"hands_played":1},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":6,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Club"},"chips":250,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_A","card":{"suit":"Spades","value":"Ace","name":"Ace of Spades"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Spades","original_value":"Ace","name":"Ace of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_A","card":{"suit":"Hearts","value":"Ace","name":"Ace of Hearts"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":0,"nominal":11,"value":"Ace","suit":"Hearts","original_value":"Ace","name":"Ace of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_A","card":{"suit":"Clubs","value":"Ace","name":"Ace of Clubs"}},"facing":"front","label":"Base Card","base":{"id":14,"times_played":1,"nominal":11,"value":"Ace","suit":"Clubs","original_value":"Ace","name":"Ace of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"S_K","card":{"suit":"Spades","value":"King","name":"King of Spades"}},"facing":"front","label":"Base Card","base":{"id":13,"times_played":1,"nominal":10,"value":"King","suit":"Spades","original_value":"King","name":"King of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_8","card":{"suit":"Hearts","value":"8","name":"8 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Hearts","original_value":"8","name":"8 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_6","card":{"suit":"Clubs","value":"6","name":"6 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":1,"nominal":6,"value":"6","suit":"Clubs","original_value":"6","name":"6 of Clubs"},"highlighted":false,"debuff":true},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103196971} +{"function":{"arguments":{"action":"play_hand","cards":[0,1,2,7]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":3,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":2,"voucher":[],"hands_played":2},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":7,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Club"},"chips":822,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"S_Q","card":{"suit":"Spades","value":"Queen","name":"Queen of Spades"}},"facing":"front","label":"Base Card","base":{"id":12,"times_played":0,"nominal":10,"value":"Queen","suit":"Spades","original_value":"Queen","name":"Queen of Spades"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_J","card":{"suit":"Clubs","value":"Jack","name":"Jack of Clubs"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":2,"nominal":10,"value":"Jack","suit":"Clubs","original_value":"Jack","name":"Jack of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"D_J","card":{"suit":"Diamonds","value":"Jack","name":"Jack of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":11,"times_played":1,"nominal":10,"value":"Jack","suit":"Diamonds","original_value":"Jack","name":"Jack of Diamonds"},"highlighted":true,"debuff":false},{"config":{"card_key":"H_8","card":{"suit":"Hearts","value":"8","name":"8 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Hearts","original_value":"8","name":"8 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"C_6","card":{"suit":"Clubs","value":"6","name":"6 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":1,"nominal":6,"value":"6","suit":"Clubs","original_value":"6","name":"6 of Clubs"},"highlighted":false,"debuff":true},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_2","card":{"suit":"Diamonds","value":"2","name":"2 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":2,"times_played":0,"nominal":2,"value":"2","suit":"Diamonds","original_value":"2","name":"2 of Diamonds"},"highlighted":true,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103198722} +{"function":{"arguments":{"action":"play_hand","cards":[1,3,4,5,6]},"name":"play_hand_or_discard"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":3,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":1,"voucher":[],"hands_played":3},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":8,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Club"},"chips":1062,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_T","card":{"suit":"Hearts","value":"10","name":"10 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Hearts","original_value":"10","name":"10 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_8","card":{"suit":"Hearts","value":"8","name":"8 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":0,"nominal":8,"value":"8","suit":"Hearts","original_value":"8","name":"8 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"D_8","card":{"suit":"Diamonds","value":"8","name":"8 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":1,"nominal":8,"value":"8","suit":"Diamonds","original_value":"8","name":"8 of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"H_7","card":{"suit":"Hearts","value":"7","name":"7 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":7,"times_played":0,"nominal":7,"value":"7","suit":"Hearts","original_value":"7","name":"7 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_6","card":{"suit":"Clubs","value":"6","name":"6 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":6,"times_played":1,"nominal":6,"value":"6","suit":"Clubs","original_value":"6","name":"6 of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"H_5","card":{"suit":"Hearts","value":"5","name":"5 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":5,"times_played":0,"nominal":5,"value":"5","suit":"Hearts","original_value":"5","name":"5 of Hearts"},"highlighted":true,"debuff":false},{"config":{"card_key":"C_4","card":{"suit":"Clubs","value":"4","name":"4 of Clubs"}},"facing":"front","label":"Base Card","base":{"id":4,"times_played":1,"nominal":4,"value":"4","suit":"Clubs","original_value":"4","name":"4 of Clubs"},"highlighted":true,"debuff":true},{"config":{"card_key":"D_3","card":{"suit":"Diamonds","value":"3","name":"3 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Diamonds","original_value":"3","name":"3 of Diamonds"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":8}},"state":1},"timestamp_ms":1753103200458} +{"function":{"arguments":[],"name":"go_to_menu"},"game_state":{"jokers":[{"label":"Jolly Joker","config":{"center":{"effect":"Type Mult","cost_mult":1,"_u":true,"set":"Joker","pos":{"y":0,"x":2},"order":6,"unlocked":true,"discovered":true,"alerted":true,"cost":3,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_jolly","_discovered_unlocked_overwritten":true,"_saved_d_u":true,"rarity":1,"name":"Jolly Joker","config":{"t_mult":8,"type":"Pair"},"_d":false}}},{"label":"Photograph","config":{"center":{"name":"Photograph","config":{"extra":2},"_saved_d_u":true,"_discovered_unlocked_overwritten":true,"order":78,"unlocked":true,"discovered":true,"alerted":true,"cost":5,"blueprint_compat":true,"perishable_compat":true,"eternal_compat":true,"key":"j_photograph","pos":{"y":13,"x":2},"rarity":1,"_u":true,"set":"Joker","_d":false}}}],"game":{"pseudorandom":[],"voucher_text":"","max_jokers":2,"bankrupt_at":0,"uncommon_mod":1,"base_reroll_cost":5,"previous_round":[],"round_scores":[],"round_bonus":[],"dollars":18,"shop":[],"round":3,"selected_back":{"name":"Red Deck"},"used_vouchers":[],"starting_params":[],"current_round":{"discards_left":1,"discards_used":3,"hands_left":0,"voucher":[],"hands_played":4},"skips":3,"bosses_used":[],"unused_discards":1,"hands_played":9,"won":false,"seeded":true,"tags":[],"blind_on_deck":"Boss","smods_version":"1.0.0~BETA-0706c","win_ante":8,"probabilities":[],"tarot_rate":4,"planet_rate":4,"playing_card_rate":0,"last_blind":{"boss":true,"name":"The Club"},"chips":1262,"discount_percent":0,"interest_cap":25,"interest_amount":1,"inflation":0,"stake":1},"hand":{"cards":[{"config":{"card_key":"H_T","card":{"suit":"Hearts","value":"10","name":"10 of Hearts"}},"facing":"front","label":"Base Card","base":{"id":10,"times_played":0,"nominal":10,"value":"10","suit":"Hearts","original_value":"10","name":"10 of Hearts"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_8","card":{"suit":"Diamonds","value":"8","name":"8 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":8,"times_played":1,"nominal":8,"value":"8","suit":"Diamonds","original_value":"8","name":"8 of Diamonds"},"highlighted":false,"debuff":false},{"config":{"card_key":"D_3","card":{"suit":"Diamonds","value":"3","name":"3 of Diamonds"}},"facing":"front","label":"Base Card","base":{"id":3,"times_played":0,"nominal":3,"value":"3","suit":"Diamonds","original_value":"3","name":"3 of Diamonds"},"highlighted":false,"debuff":false}],"config":{"highlighted_limit":5,"card_limit":8,"card_count":3}},"state":4},"timestamp_ms":1753103203102}