10 KiB
Game Center Integration - CasinoKit (Shared Infrastructure)
This document outlines the shared Game Center infrastructure that will be used by all casino games in the workspace.
Overview
Game Center will be integrated for achievements only (no leaderboards) to avoid cheating concerns with client-side casino games. All shared Game Center logic will live in CasinoKit to avoid code duplication.
Shared Components to Add
1. GameCenterManager (Core Service)
Location: CasinoKit/Sources/CasinoKit/GameCenter/GameCenterManager.swift
Purpose: Centralized manager for all Game Center operations.
Features:
- Authentication with Game Center
- Achievement submission
- Achievement progress tracking
- Error handling and retry logic
- Availability checking
- Privacy-friendly (doesn't force sign-in)
Key Methods:
@MainActor
@Observable
class GameCenterManager {
static let shared = GameCenterManager()
var isAuthenticated: Bool = false
var isAvailable: Bool = true
var localPlayer: GKLocalPlayer?
// Authentication
func authenticate()
// Achievement management
func submitAchievement(_ identifier: String, percentComplete: Double)
func incrementAchievement(_ identifier: String, by value: Double)
func resetAchievements() // For testing only
func loadAchievements() -> [GKAchievement]
// UI presentation
func showGameCenterDashboard()
}
Implementation Notes:
- Use async/await APIs (iOS 14+)
- Silent authentication (no blocking UI)
- Gracefully handle Game Center being disabled
- Cache authentication state
- Support offline mode (queue submissions for later)
2. Achievement Configuration Protocol
Location: CasinoKit/Sources/CasinoKit/GameCenter/AchievementDefinition.swift
Purpose: Type-safe achievement definitions per game.
protocol AchievementDefinition {
var identifier: String { get }
var title: String { get }
var description: String { get }
var maxProgress: Int { get }
var iconName: String { get }
var isIncremental: Bool { get }
}
// Example usage in game:
enum BlackjackAchievement: String, AchievementDefinition {
case strategyStudent = "blackjack_strategy_50"
case cardCounter = "blackjack_card_counting_25"
// ...
var identifier: String {
"com.yourdomain.blackjack.\(rawValue)"
}
var title: String {
switch self {
case .strategyStudent: return String(localized: "Strategy Student")
case .cardCounter: return String(localized: "Card Counter")
}
}
// ... other properties
}
3. Game Center Access Point View
Location: CasinoKit/Sources/CasinoKit/Views/GameCenter/GameCenterAccessPoint.swift
Purpose: Standard UI component for showing Game Center status.
Features:
- Shows authentication state
- Displays achievement progress
- Links to Game Center dashboard
- Optional placement (top bar or settings)
- Respects user privacy preferences
struct GameCenterAccessPoint: View {
@State private var manager = GameCenterManager.shared
var body: some View {
// Small floating button or status indicator
// Shows GC icon when authenticated
// Tapping opens achievement list
}
}
4. Achievement Tracking Helper
Location: CasinoKit/Sources/CasinoKit/GameCenter/AchievementTracker.swift
Purpose: Helper for games to track achievement progress locally before submitting.
@MainActor
@Observable
class AchievementTracker<Achievement: AchievementDefinition> {
private var progress: [String: Int] = [:]
func increment(_ achievement: Achievement, by value: Int = 1)
func getProgress(_ achievement: Achievement) -> Int
func checkAndSubmit(_ achievement: Achievement)
func reset() // For new game sessions
}
Why This Helps:
- Games can track progress locally (fast)
- Batch submissions to Game Center (efficient)
- Handles the "report once at 100%" logic for non-incremental achievements
5. Settings Integration
Location: CasinoKit/Sources/CasinoKit/Views/Settings/GameCenterSettingsSection.swift
Purpose: Standard settings UI for Game Center.
struct GameCenterSettingsSection: View {
@State private var manager = GameCenterManager.shared
var body: some View {
SheetSection(title: "GAME CENTER", icon: "gamecontroller.fill") {
if manager.isAvailable {
HStack {
Text("Status")
Spacer()
Text(manager.isAuthenticated ? "Connected" : "Not Connected")
.foregroundStyle(.secondary)
}
if manager.isAuthenticated {
Button("View Achievements") {
manager.showGameCenterDashboard()
}
Button("Sign Out") {
// Note: Can't actually sign out from app,
// just stop authenticating
}
} else {
Button("Connect to Game Center") {
Task { await manager.authenticate() }
}
}
} else {
Text("Game Center is not available")
.foregroundStyle(.secondary)
}
}
}
}
6. Achievement Toast Notification
Location: CasinoKit/Sources/CasinoKit/Views/GameCenter/AchievementToast.swift
Purpose: Show celebratory notification when achievement is earned (optional enhancement).
Features:
- Brief animation when achievement unlocks
- Shows achievement icon and title
- Auto-dismisses after 3 seconds
- Doesn't block gameplay
- Similar to iOS system notifications
struct AchievementToast: View {
let achievement: String
let title: String
@State private var isShowing = false
var body: some View {
// Slide-in notification from top
// Shows achievement icon + title
// Fades out after delay
}
}
File Structure
CasinoKit/Sources/CasinoKit/
├── GameCenter/
│ ├── GameCenterManager.swift # Core manager (authentication, submission)
│ ├── AchievementDefinition.swift # Protocol for type-safe achievements
│ ├── AchievementTracker.swift # Local progress tracking helper
│ └── GameCenterError.swift # Custom error types
├── Views/
│ └── GameCenter/
│ ├── GameCenterAccessPoint.swift # Status indicator/button
│ ├── GameCenterSettingsSection.swift # Settings UI component
│ └── AchievementToast.swift # Achievement unlock notification
└── Resources/
└── Localizable.xcstrings # Add GC-related strings
Localization Strings to Add
Add to CasinoKit/Resources/Localizable.xcstrings:
Game Center
Connected
Not Connected
Sign Out
View Achievements
Game Center is not available
Achievement Unlocked!
Connect to Game Center
App Store Connect Configuration
Note: Each game will need its own achievements configured in App Store Connect.
Achievement Naming Convention
Use consistent identifier format:
com.yourdomain.{game}.{achievement_key}
Examples:
com.yourdomain.blackjack.strategy_student
com.yourdomain.blackjack.card_counter
com.yourdomain.baccarat.dragon_master
com.yourdomain.baccarat.natural_high
Achievement Assets
Each achievement needs:
- 512x512px icon (1x)
- 1024x1024px icon (2x)
Design Guidelines:
- Use SF Symbols where appropriate (consistent with app design)
- Match app color scheme
- Clear, recognizable icons
- Consider accessibility (high contrast)
Implementation Order
- GameCenterManager - Core authentication and submission logic
- AchievementDefinition protocol - Type system
- AchievementTracker - Helper for games to use
- GameCenterSettingsSection - UI integration
- GameCenterAccessPoint - Optional status indicator
- AchievementToast - Optional enhancement
Testing Strategy
Local Testing
- Test with Game Center sandbox account
- Verify authentication flow
- Test achievement submission
- Test offline behavior
- Test achievement progress tracking
TestFlight Testing
- Required for full Game Center integration testing
- Verify achievements appear correctly
- Test achievement notifications
- Verify localization
Debug Features to Add
#if DEBUG
extension GameCenterManager {
func resetAllAchievements() {
// Only available in debug builds
}
func logAchievementStatus() {
// Print all achievement progress
}
}
#endif
Privacy Considerations
- No forced sign-in - Game Center is entirely optional
- Graceful degradation - App works fully without Game Center
- No data collection - Only submit achievement progress, nothing else
- User control - Easy to see status and disconnect
Performance Considerations
- Authenticate once - On app launch, silent background auth
- Batch submissions - Don't submit every increment immediately
- Cache state - Remember authentication status
- Async operations - Never block UI on Game Center calls
- Offline queue - Store failed submissions, retry later
Future Enhancements (Optional)
- Challenge Mode - Separate game mode with fixed rules and leaderboards
- Friend Comparison - Show achievement progress vs friends
- Weekly Challenges - Time-limited achievement variants
- Leaderboards - Only if Challenge Mode is added with anti-cheat
Dependencies
- GameKit framework - Apple's Game Center SDK
- No third-party dependencies - Pure Apple APIs
Estimated Effort
- CasinoKit infrastructure: 4-6 hours
- Per-game integration: 2-3 hours each
- App Store Connect setup: 1-2 hours
- Testing & polish: 2-3 hours
Total: ~12-16 hours for complete implementation across both games.
Next Steps
- Review this plan
- See game-specific plans in
Blackjack/GAME_CENTER_PLAN.mdandBaccarat/GAME_CENTER_PLAN.md - Configure achievements in App Store Connect
- Implement CasinoKit infrastructure first
- Integrate into games second
- Test with TestFlight
This shared infrastructure approach ensures consistency across all casino games while avoiding code duplication.