Game Rules Engine
Relevant source files
The following files were used as context for generating this wiki page:
The Game Rules Engine is the core logical component of Dreamcats, responsible for enforcing gameplay mechanics, managing state transitions, and calculating scores. It operates primarily within the Convex backend to ensure a single authoritative state across all clients. The engine handles the lifecycle of a game from the initial setup and "Peeking" phase through the main gameplay loop to the final "Pobudka" (Wake Up) call and scoring.
The engine is designed as a state machine where actions (mutations) trigger transitions between predefined phases. It ensures that rules regarding deck composition, turn order, and special card powers are strictly followed, providing a consistent experience for online multiplayer, local hot-seat, and solo AI modes.
Sources: RULES.md:1-20, convex/actions.ts:21-60, README.md
Core Game Lifecycle
The game progresses through several distinct phases. The engine manages these transitions via the performAction mutation, which validates the current phase before allowing specific player moves.
Phase State Machine
The following diagram illustrates the high-level transitions managed by the rules engine:
The engine transitions from peeking to playing only after every player has confirmed looking at exactly 2 of their cards.
Sources: convex/actions.ts:318-356, convex/tests/rooms-and-games.test.ts:40-52
Component Specifications
Deck Composition
The engine utilizes a 54-card deck with specific distributions that impact the probability of scoring.
| Card Type | Count | Value/Power |
|---|---|---|
| Standard Number | 36 | 0 through 8 (4 of each) |
| Cat Cards | 9 | Value 9 (High penalty) |
| Special: Weź 2 | 3 | "Take 2" - Draw/Choose power |
| Special: Podejrzyj 1 | 3 | "Peek 1" - Look at any card |
| Special: Zamień 2 | 3 | "Swap 2" - Blindly swap cards |
Sources: RULES.md:14-25
Player Actions and Validation
The engine exposes a central API for gameplay via the performAction mutation. Every action is validated against the currentPlayerIndex and the current gamePhase.
Gameplay Logic and Special Powers
The Turn Loop
On a player's turn, the engine enforces two primary paths:
- Draw from Discard: The player takes a visible card but is mandated to swap it with a card in their dream.
- Draw from Deck: The player may swap, discard, or—if the card is special—activate its power.
Sources: RULES.md:42-58, convex/actions.ts:376-425
Special Action Handling
Special powers are only active if the card is drawn from the deck and immediately discarded. The engine manages sub-phases for complex actions like "Swap 2" and "Take 2".
- Take 2: The engine draws 2 additional cards, stores them in
tempCards, and enters theaction_take_2phase until the player chooses one. - Peek 1: The engine enters
action_peek_1, allowing the player to view any card (marked viahasBeenPeekedin the schema). - Swap 2: A two-step process (
action_swap_2_select_1andaction_swap_2_select_2) where the engine swaps card positions across player hands without revealing them.
Sources: convex/actions.ts:466-565, scripts/ai-agent.ts:250-290
Scoring and Termination
"POBUDKA!" (Wake Up) Logic
A round ends when a player triggers the "Pobudka" action. The rules engine then executes the following scoring algorithm:
- Sum Values: Totals the values of all 4 cards in every player's "Dream."
- Caller Risk:
- If Caller Score $\le$ all other players: Caller takes their sum as points.
- If Caller Score $>$ any other player: Caller takes their sum + 5 penalty points.
- Accumulation: Adds the round points to the players' total scores stored in the
playerstable.
Sources: RULES.md:80-94, convex/actions.ts:161-218
Termination Conditions
The engine monitors the players.score fields after every round.
- Game End: Triggered when any player reaches or exceeds 100 points.
- Winner: The player with the strictly lowest total score is declared the winner in
gameWinnerName.
Sources: RULES.md:96-100, convex/actions.ts:208-218
Data Structures
The engine relies on a strictly typed schema to maintain game integrity.
| Field | Type | Description |
|---|---|---|
gamePhase | Enum | Controls allowed actions (e.g., playing, holding_card) |
drawPile | Array | The hidden stack of remaining cards |
discardPile | Array | The visible stack of discarded cards |
hand | Array | 4 slots per player containing card, isFaceUp, and hasBeenPeeked |
version | Number | Incremental counter to prevent stale state writes |
Sources: convex/schema.ts:34-42, convex/tests/rooms-and-games.test.ts:13-60
Conclusion
The Game Rules Engine provides a robust, centralized authority for Dreamcats. By combining a strict phase-based state machine with idempotent mutations in Convex, it ensures that complex card interactions—particularly those involving memory-based "Peeking" and hidden special powers—are handled accurately and fairly in a multiplayer environment.
Sources: README.md, convex/actions.ts:26-30