Lucky Wheel
Relevant source files
The following files were used as context for generating this wiki page:
The Lucky Wheel is a player engagement feature that provides a daily bonus mechanism. It allows players to spin a wheel for a chance to win various in-game prizes, such as coins and diamonds. The feature is presented as a full-screen modal, accessible via the LuckyWheelButton component. It includes a spin cooldown timer, a progressive multiplier system, and a history of recent spins.
The wheel's state, including available spins and cooldowns, is managed within the LuckyWheel component itself. When a prize is won, the component uses a callback function, onPrizeWon, to communicate the result to its parent component.
Component Architecture
The Lucky Wheel feature is primarily composed of two React components: LuckyWheelButton and LuckyWheel.
LuckyWheelButton: A simple button component that serves as the entry point. It displays a "Daily Bonus" call to action and manages the visibility of theLuckyWheelmodal.LuckyWheel: The main component that renders the entire feature, including the wheel itself, player information, spin controls, and progress indicators. It encapsulates all the logic for spinning, prize calculation, and state management.
The diagram below illustrates the relationship between the components and the data flow.
LuckyWheel Component
This is the core component that renders the modal and handles all functionality.
Props
The component receives the following props to function:
| Prop | Type | Description |
|---|---|---|
isOpen | boolean | Controls the visibility of the wheel modal. |
onClose | () => void | Callback function to close the modal. |
playerName | string | The current player's name. |
playerLevel | number | The current player's level. |
playerChips | number | The current player's chip balance. |
playerDiamonds | number | The current player's diamond balance. |
onPrizeWon | (prize: WheelPrize, multiplier: number) => void | Callback triggered after a spin to award the prize. |
Sources: components/lucky-wheel.tsx:12-20, components/lucky-wheel-button.tsx:34-36
Internal State
The component manages its own state using the useState hook and the WheelState type.
| State Variable | Type | Description |
|---|---|---|
wheelState | WheelState | An object containing the core state of the wheel (spins, progress, history). |
isSpinning | boolean | A flag to indicate if the wheel animation is currently active. |
rotation | number | The target rotation degree for the wheel animation. |
timeUntilNextSpin | string | A formatted string showing the remaining time for the next free spin. |
Sources: components/lucky-wheel.tsx:25-32
Data Structures
The feature relies on several custom types defined in types/lucky-wheel.ts to structure its data.
Type Definitions
The diagram below shows the relationships between the main data structures.
Sources: types/lucky-wheel.ts:1-19
Prize Configuration
The available prizes on the wheel are defined in an array in lib/wheel-prizes.ts. This file is not present in the provided context, but its usage is referenced. The structure of each prize object conforms to the WheelPrize interface.
Sources: components/lucky-wheel.tsx:8
Core Logic
The primary logic for the Lucky Wheel's functionality resides within the LuckyWheel component.
Spin Mechanism
The handleSpin function orchestrates the entire spinning process.
The flow for handling a spin is as follows:
- Check if spins are available and if the wheel is not already spinning.
- Set
isSpinningtotrue. - Randomly select a
prizeIndex. - Calculate the target rotation for the wheel animation.
- Determine the prize
multiplierbased on the currentspinProgress. - After a 5-second timeout (for the animation), invoke the
onPrizeWoncallback. - Update the
wheelState:- Decrement
spinsAvailable. - Set a 4-hour cooldown for
nextSpinTime. - Increment
spinProgress. - Update
spinHistory.
- Decrement
- Set
isSpinningback tofalse.
Sources: components/lucky-wheel.tsx:91-131
Prize Multiplier
A multiplier is applied to the won prize based on the player's spin progress. The progress bar fills up with each spin, and reaching certain thresholds activates a higher multiplier.
Spin Progress (spinProgress) | Multiplier |
|---|---|
| 0 - 2 | 1x |
| 3 - 6 | 2x |
| 7+ (resets to 0 after spin) | 3x |
The spinProgress increments by 1 after each spin. If it reaches 7, it resets to 0 on the next spin.
Sources: components/lucky-wheel.tsx:107-112, components/lucky-wheel.tsx:120, components/lucky-wheel.tsx:313-320, components/lucky-wheel.tsx:321-328
Spin Cooldown
After a spin is used, a cooldown period is initiated before the player can receive another free spin.
- The cooldown is hardcoded to 4 hours.
- The
useEffecthook sets up an interval that runs every second to calculate and display thetimeUntilNextSpin. - When the timer reaches zero,
spinsAvailableis incremented, and thenextSpinTimeis reset tonull.
// Setting the cooldown after a spin
setWheelState((prev) => ({
// ...
nextSpinTime: new Date(Date.now() + 4 * 60 * 60 * 1000), // 4 hours
// ...
}));
Sources: components/lucky-wheel.tsx:41-70, components/lucky-wheel.tsx:119
UI and Styling
The Lucky Wheel UI is a complex composition of styled div elements, SVG for the segments, and custom CSS for animations and layout.
Key UI Elements
| Element | Description | Source Files - |
|---|---|---|
| Player Header | Displays the player's name, level, chip count, and diamond count at the top of the screen. | components/lucky-wheel.tsx:143-171 - |
| Spin Ticket | Shows the number of available spins and the countdown timer for the next free spin. | components/lucky-wheel.tsx:180-200 - |
| Wheel SVG | The wheel itself is rendered using SVG, with <path> elements for each segment and <text> for the prize labels. The colors of the segments alternate. | components/lucky-wheel.tsx:226-253 - |
- | Spin Progress Bar | A visual indicator of the
spinProgressstate, showing how close the player is to the next multiplier bonus (x2 at 3 spins, x3 at 7 spins). |components/lucky-wheel.tsx:283-332- |
| Color Selection | Buttons allowing the player to change the theme color of the wheel. This is a purely cosmetic feature and does not affect prizes. The selected color is stored inwheelState.selectedColor. |components/lucky-wheel.tsx:335-353- |
Animations
- Wheel Rotation: The wheel's rotation is handled by a CSS transition on the
transformproperty. Thedurationis set to 5000ms with anease-outtiming function. - Glow/Pulse Effects: A pulsing glow effect is applied to the wheel and center circle using CSS animations to draw the user's attention. The
animate-pulseclass is used.
Sources: components/lucky-wheel.tsx:216-217, app/globals.css:168-177, components/lucky-wheel.tsx:205