7.3 KiB
Onboarding System Implementation Summary
Overview
A comprehensive, non-intrusive onboarding system has been implemented for both Blackjack and Baccarat games using the Sherpa walkthrough framework. The system provides a great first-time user experience without annoying experienced players.
Architecture
The onboarding system uses:
- Sherpa - A SwiftUI walkthrough framework for spotlight-based guided tours
- OnboardingState - Tracks completion status and hint visibility
- WelcomeSheet - First-launch welcome screen with feature highlights
Sherpa Integration
Package Dependency
Sherpa is added as a dependency in CasinoKit/Package.swift:
dependencies: [
.package(url: "https://github.com/mbrucedogs/Sherpa.git", branch: "develop")
]
It's re-exported from CasinoKit, so games only need to import CasinoKit.
App Structure
Each game wraps its content in SherpaContainerView:
@main
struct BlackjackApp: App {
var body: some Scene {
WindowGroup {
SherpaContainerView(configuration: .default) {
AppLaunchView(config: .blackjack) {
ContentView()
}
}
}
}
}
Walkthrough Tags
Each game defines walkthrough steps using SherpaTags:
enum BlackjackWalkthroughTags: SherpaTags {
case bettingZone
case dealButton
case playerActions
func makeCallout() -> Callout {
switch self {
case .bettingZone:
return .localizedLabeled(
"walkthrough.bettingZone",
systemImage: "hand.tap.fill",
edge: .top
)
// ...
}
}
}
View Tagging
Views are tagged for spotlight highlighting:
BettingZoneView(state: state, selectedChip: selectedChip)
.sherpaTag(BlackjackWalkthroughTags.bettingZone)
BettingActionsView(...)
.sherpaTag(BlackjackWalkthroughTags.dealButton)
Activation
The walkthrough is activated when the user taps "Show Me How":
struct GameTableView: View, SherpaDelegate {
@State private var isWalkthroughActive = false
var body: some View {
mainGameView(state: state)
.sherpa(isActive: isWalkthroughActive, tags: BlackjackWalkthroughTags.self, delegate: self)
}
private func startWalkthrough() {
isWalkthroughActive = true
}
// MARK: - SherpaDelegate
func onWalkthroughComplete(sherpa: Sherpa) {
isWalkthroughActive = false
state.onboarding.completeWelcome()
}
func onWalkthroughSkipped(sherpa: Sherpa, atStep: Int, totalSteps: Int) {
isWalkthroughActive = false
state.onboarding.completeWelcome()
}
}
Components
1. OnboardingState.swift (CasinoKit)
- Tracks first-time user progress
- Persists state to UserDefaults
- Game-specific identifiers (separate state per game)
Key Methods:
completeWelcome()- Mark welcome/walkthrough as completedskipOnboarding()- Skip onboarding entirelyreset()- Clear all onboarding data (for testing)
2. WelcomeSheet.swift (CasinoKit)
- First-launch welcome screen
- Lists key features with icons
- Two CTAs: "Show Me How" (starts walkthrough) or "Start Playing" (skip)
- Fully localized
3. WalkthroughTags (Per Game)
- Defines walkthrough steps for each game
- Provides localized callout content
- Specifies icons and positioning
Walkthrough Steps
Blackjack
| Step | Tag | Description |
|---|---|---|
| 1 | bettingZone |
Highlights betting area - "Select a chip and tap the bet area" |
| 2 | dealButton |
Highlights deal button - "Tap Deal to start the round" |
| 3 | playerActions |
Highlights action buttons - "Choose your action based on the hint above" |
Baccarat
| Step | Tag | Description |
|---|---|---|
| 1 | bettingZone |
Highlights betting table - "Select a chip and tap a bet zone" |
| 2 | dealButton |
Highlights deal button - "Tap Deal to start the round" |
User Flow
First Launch:
- App loads
- Welcome sheet appears automatically after 500ms delay
- User chooses:
- "Show Me How": Starts Sherpa walkthrough with spotlight focus
- "Start Playing": Skips walkthrough, marks onboarding complete
Walkthrough Experience:
- Screen dims with spotlight on highlighted element
- Callout tooltip explains the element
- User taps to advance to next step
- Progress indicator shows current step
- Skip button available at all times
Subsequent Launches:
- Welcome sheet never shows again
- Walkthrough can be replayed via settings (if implemented)
Localization
Walkthrough strings are stored in each game's Localizable.xcstrings:
| Key | English | Spanish (MX) | French (CA) |
|---|---|---|---|
walkthrough.bettingZone |
Select a chip and tap the bet area | Selecciona una ficha y toca el área de apuesta | Sélectionnez un jeton et touchez la zone de mise |
walkthrough.dealButton |
Tap Deal to start the round | Toca Repartir para comenzar la ronda | Touchez Distribuer pour commencer la manche |
walkthrough.playerActions |
Choose your action based on the hint above | Elige tu acción según la sugerencia de arriba | Choisissez votre action selon l'indice ci-dessus |
Benefits of Sherpa Migration
| Before (TooltipManager) | After (Sherpa) |
|---|---|
| Simple tooltips without focus | Spotlight effect highlights elements |
| Manual positioning | Smart auto-positioning |
| No navigation controls | Back/Next/Skip controls |
| No progress indicator | Step indicator dots |
| Basic animations | Smooth transitions with haptics |
| Custom implementation | Well-tested framework |
| 10+ languages | 10 languages built-in |
Files Changed
CasinoKit
Package.swift- Added Sherpa dependencyExports.swift- Re-exports Sherpa- Deleted:
TooltipManager.swift,ContextualTooltip.swift
Blackjack
- Added:
Models/WalkthroughTags.swift - Modified:
BlackjackApp.swift,GameTableView.swift,ActionButtonsView.swift - Modified:
BlackjackTableView.swift(added sherpaTag) - Modified:
Localizable.xcstrings(walkthrough strings)
Baccarat
- Added:
Models/WalkthroughTags.swift - Modified:
BaccaratApp.swift,GameTableView.swift,ActionButtonsView.swift - Modified:
BettingTableView.swift(added sherpaTag) - Modified:
Localizable.xcstrings(walkthrough strings)
Best Practices Followed
✅ Non-intrusive: All onboarding is skippable ✅ Sequential flow: Clear progression through steps ✅ Visual focus: Spotlight draws attention to key elements ✅ Haptic feedback: Tactile response on step changes ✅ Localized: All strings use String Catalog ✅ Accessible: VoiceOver announcements for each step ✅ Persistent: User's completion status is saved ✅ Game-specific: Each game has independent walkthrough
Testing
Reset for Testing:
Add this to a development menu if needed:
Button("Reset Onboarding") {
gameState.onboarding.reset()
}
Manual Testing:
- Delete app, reinstall, verify welcome sheet appears
- Tap "Show Me How", verify spotlight walkthrough starts
- Navigate through all steps
- Verify completion callback fires
- Relaunch app, verify welcome doesn't show again