Audio & Haptics
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Audio & Haptics system in Dreamcats provides an immersive sensory experience designed to complement its "dreamy and surreal" aesthetic. By utilizing spatialized and interactive sound effects, the system reinforces game actions such as card flipping, drawing, and special moves. The high-level objective is to create a soundscape that balances whimsical comfort with the tension of "nightmare" cards, using a sparse and atmospheric approach inspired by traditional motifs.
Sources: README.md:6, RULES.md:143-150
Audio Architecture
The audio system is built upon the Howler.js library, which handles audio decoding and playback across various browser environments. Audio is managed through a custom React hook, useSounds, which implements lazy loading for sound assets to optimize initial load times. Sound playback is gated by user preferences stored both in local state and persisted via the Convex backend.
Sources: README.md:27, src/hooks/use-sounds.ts:46-51
Sound Types and Configuration
The project defines a specific set of sound triggers mapped to game events. Each sound is configured with specific volume and playback rate settings to ensure they remain subtle and avoid audio warping.
| Sound Type | Asset Path | Volume | Playback Rate |
|---|---|---|---|
flip | /sounds/flip.mp3 | 0.22 | 1.3 |
draw | /sounds/draw.mp3 | 0.22 | 1.2 |
shuffle | /sounds/shuffle.mp3 | 0.20 | 1.15 |
click | /sounds/click.mp3 | 0.30 | Default |
chat | /sounds/chat.mp3 | 0.35 | Default |
pobudka | /sounds/pobudka.mp3 | 0.50 | Default |
win | /sounds/win.mp3 | 0.45 | Default |
lose | /sounds/lose.mp3 | 0.40 | Default |
Sources: src/hooks/use-sounds.ts:16-43
Audio Flow Control
The playback logic follows a strict validation path, checking the soundEnabled state from the global Zustand store and fallback localStorage before initializing a Howl instance.
The system ensures resources are cleaned up by unloading all Howl instances when the hook unmounts.
Sources: src/hooks/use-sounds.ts:46-77
User Preferences and Persistence
Audio settings are highly integrated with the user's profile. Preferences are synchronized between the client-side UI and the Convex database.
Preference Management Logic
The userPreferences module handles the persistence of the soundEnabled flag. This allows a user's choice to toggle sound to persist across different devices and sessions.
Sound Toggle Component
The SoundToggle.tsx component serves as the primary UI entry point for audio control. It uses the Volume2 and VolumeX icons from lucide-react to reflect the current state and triggers the toggleSound action in the global store.
// src/components/SoundToggle.tsx:22-38
<Button
variant="outline"
size="icon"
aria-label={soundEnabled ? t("preferences.soundOn") : t("preferences.soundOff")}
onClick={toggleSound}
className={cn("touch-target rounded-full ...")}
>
{soundEnabled ? <Volume2 className="h-4 w-4" /> : <VolumeX className="h-4 w-4" />}
</Button>
Sources: src/components/SoundToggle.tsx:22-38
Haptics and Interaction
While the codebase primarily focuses on audio through Howler.js, interaction feedback is also handled through CSS-based "pop" animations and touch-friendly targets. The index.css file defines a card-pop animation that provides visual haptic-like feedback when cards are swapped or changed, simulating a physical lift.
- Card Pop: Scales the element to 1.06 and shifts it -6px vertically to simulate a "mini hover" or selection lift.
- Touch Targets: Standardized at a minimum of 44x44px for mobile devices to ensure reliable interaction.
Sources: src/index.css:262-277, src/index.css:166-171
Conclusion
The Audio & Haptics system in Dreamcats is a utility-driven module that prioritizes performance through lazy loading and atmospheric consistency through fine-tuned playback rates. By integrating with Convex for preference persistence and utilizing Howler.js for robust playback, the project delivers a reliable and immersive soundscape that scales with the game's state transitions.