playe-developer-sdk
v1.0.17
Published
Enhanced Game Developer SDK for browser-based projects - integrate games with campaigns, leaderboards, and anti-cheat protection
Maintainers
Readme
🎮 Playe Developer SDK
A browser-based SDK for integrating games with the Playe platform. Provides game session management, campaign integration, leaderboards, and integrity verification.
✨ Features
- 🎮 Game Session Management - Initialize, start, update, and complete game sessions
- 🛡️ Integrity Verification - Built-in session integrity with cryptographic hashing
- 🏆 Campaign Integration - Access campaign information, leaderboards, and player attempts
- 🔄 Anti-Cheat Protection - Advanced validation, heartbeat mechanisms, and session monitoring
- 📱 Device Detection - Automatic device information and fingerprinting
- 🔧 Developer Tools - Test game sessions and debugging utilities
- 📊 Real-time Updates - Progress tracking and live leaderboards
- ⚡ Browser Optimized - Lightweight and fast for web games with automatic retry logic
🚀 Installation
NPM
npm install playe-developer-sdk
# or
yarn add playe-developer-sdk
# or
pnpm add playe-developer-sdkCDN
<script src="https://unpkg.com/playe-developer-sdk@latest/dist/playe-sdk.umd.min.js"></script>Workspace
{
"dependencies": {
"@workspace/playe-developer-sdk": "workspace:*"
}
}📖 Quick Start
NPM Usage
import { createPlayeSDK } from "playe-developer-sdk";
// Initialize SDK
const sdk = createPlayeSDK({
apiBaseUrl: "https://api.playe.com",
apiKey: "your-api-key",
enableDebugMode: true,
});
// Initialize game session (gets sessionId from URL)
const session = await sdk.initializeGameSession();
// Start game
await sdk.startGameSession({
difficulty: "normal",
mode: "classic",
});
// Update progress
await sdk.updateGameProgress({
currentScore: 1500,
elapsedTime: 120,
gameState: {
level: 3,
lives: 2,
powerUps: ["speed", "shield"],
},
achievements: [
{
id: "level-3",
name: "Level 3 Complete",
unlockedAt: new Date().toISOString(),
},
],
});
// Complete game
const result = await sdk.completeGame({
finalScore: 2500,
validationChecksum: "client-checksum",
gameMetrics: {
totalPlayTime: 300,
actionsPerformed: 150,
powerUpsUsed: 5,
levelsCompleted: 5,
},
finalGameState: {
level: 5,
finalLives: 1,
},
});CDN Usage
<script src="https://unpkg.com/playe-developer-sdk@latest/dist/playe-sdk.umd.min.js"></script>
<script>
const sdk = PlayeSDK.createPlayeSDK({
apiBaseUrl: 'https://api.playe.com',
apiKey: 'your-api-key',
enableDebugMode: true,
});
const session = await sdk.initializeGameSession();
console.log('Session initialized:', session.sessionId);
</script>📋 Table of Contents
🔧 API Reference
SDK Configuration
interface SDKConfig {
apiBaseUrl: string; // Required: API base URL
apiKey?: string; // Optional: API key for authentication
enableDebugMode?: boolean; // Optional: Enable debug logging
retryAttempts?: number; // Optional: Number of retry attempts (default: 3)
timeoutMs?: number; // Optional: Request timeout in ms (default: 30000)
enableOfflineMode?: boolean; // Optional: Enable offline mode (default: false)
}Core Methods
Game Session Management
// Initialize game session (gets sessionId from URL query parameter)
const session = await sdk.initializeGameSession(): Promise<GameSessionResponse>;
// Returns: { sessionId, campaignId, gameId, status, campaign, player, createdAt, expiresAt }
// Start game session
await sdk.startGameSession(config?: Record<string, any>): Promise<GameSessionResponse>;
// Returns: { sessionId, status, startTime }
// Update game progress with integrity verification
await sdk.updateGameProgress({
currentScore: number;
gameState?: Record<string, any>; // Automatically hashed for integrity
elapsedTime: number;
achievements?: Achievement[];
clientTimestamp?: string;
}): Promise<ProgressUpdateResponse>;
// Returns: { isValid, validationMessage, currentRank, isLeading, campaignStatus, warnings }
// Complete game with integrity verification
await sdk.completeGame({
finalScore: number;
validationChecksum: string;
gameMetrics?: GameMetrics;
finalGameState?: Record<string, any>; // Automatically hashed for integrity
}): Promise<GameCompletionResponse>;
// Returns: { isWinner, prizeAmount, prizeType, finalRank, totalParticipants, winnerDetails, reward, campaignResult }
// Abandon game
await sdk.abandonGame(reason?: string, lastKnownScore?: number): Promise<AbandonGameResponse>;
// Returns: { success, message, gamepassRefunded, abandonedAt }Campaign Information
// Get campaign status
await sdk.getCampaignStatus(campaignId: string, playerId?: string): Promise<CampaignStatusResponse>;
// Returns: { campaignId, status, campaignStyle, remainingGamepasses, totalParticipants,
// totalPrizePool, endDate, playerStatus, topPlayers, prizeBreakdown }
// Get leaderboard
await sdk.getLeaderboard(campaignId: string, limit?: number, playerId?: string): Promise<LeaderboardResponse>;
// Returns: { campaignId, entries, playerRank, lastUpdated, isLive }
// entries: [{ rank, playerId, displayName, score, achievedAt, isCurrentPlayer, prizeAmount }]
// Get player attempts
await sdk.getPlayerAttempts(campaignId: string, playerId: string): Promise<PlayerAttemptsResponse>;
// Returns: { playerId, campaignId, totalAttempts, remainingAttempts, attempts, stats }
// attempts: [{ sessionId, score, playedAt, duration, status, wasWinner }]
// stats: { bestScore, averageScore, totalPlayTime, firstAttempt, lastAttempt }Validation & Anti-Cheat
// Validate game session with integrity verification
await sdk.validateGameSession({
clientChecksum: string;
stateSnapshot?: Record<string, unknown>; // Automatically hashed
timingData?: unknown;
behaviorMetrics?: unknown;
}): Promise<ValidationResponse>;
// Returns: { isValid, confidenceScore, validationIssues, warnings, requiresRevalidation, validatedAt }
// Send heartbeat (usually handled automatically)
await sdk.sendHeartbeat(currentScore?: number): Promise<HeartbeatResponse>;
// Returns: { acknowledged, serverTimestamp, nextHeartbeatIn, campaignStillActive, message }Developer Tools
// Create test game session for development
await sdk.createTestGameSession(testConfig?: Record<string, any>): Promise<TestGameResponse>;
// Returns: { testSessionId, testScenario, mockCampaign, testData, expiresAt }Utility Methods
// Test SDK functionality
sdk.test('Custom test message'): void;
// Check if running in demo mode
const isDemoMode = sdk.isDemo(): boolean;
// Game lifecycle events
sdk.gameLoadingStart(): void; // Emit loading start event
sdk.gameLoadingFinished(): void; // Emit loading finished event
sdk.gamePlayStop(): void; // Stop heartbeat and emit stop event
// Clean up resources
sdk.destroy(): void; // Clean up session artifacts and stop heartbeatResponse Types
// Game Session Response
interface GameSessionResponse {
sessionId: string;
campaignId: string;
gameId: string;
status: string;
campaign: CampaignInfo;
player: PlayerInfo;
createdAt: string;
expiresAt?: string;
}
// Progress Update Response
interface ProgressUpdateResponse {
isValid: boolean;
validationMessage?: string;
currentRank: number;
isLeading: boolean;
campaignStatus?: CampaignStatusInfo;
warnings?: string[];
}
// Game Completion Response
interface GameCompletionResponse {
isWinner: boolean;
prizeAmount?: number;
prizeType?: string;
finalRank: number;
totalParticipants: number;
winnerDetails?: WinnerInfo;
reward?: RewardInfo;
campaignResult?: CampaignResultInfo;
}
// Campaign Status Response
interface CampaignStatusResponse {
campaignId: string;
status: string;
campaignStyle: string;
remainingGamepasses: number;
totalParticipants: number;
totalPrizePool: number;
endDate?: string;
playerStatus?: PlayerStatusInfo;
topPlayers?: TopPlayer[];
prizeBreakdown?: PrizeBreakdown;
}
// Leaderboard Response
interface LeaderboardResponse {
campaignId: string;
entries: LeaderboardEntry[];
playerRank?: PlayerRankInfo;
lastUpdated: string;
isLive: boolean;
}
// Validation Response
interface ValidationResponse {
isValid: boolean;
confidenceScore: number;
validationIssues: string[];
warnings: string[];
requiresRevalidation: boolean;
validatedAt: string;
}Integrity Verification Utilities
import { canonicalStringify, sha256Hex } from "playe-developer-sdk";
// Canonical JSON stringification (deterministic)
const canonical = canonicalStringify({ b: 1, a: 2 }); // '{"a":2,"b":1}'
// SHA-256 hashing
const hash = await sha256Hex("data to hash");Device Utilities
import { DeviceUtils } from "@workspace/playe-developer-sdk";
// Get device information
const deviceInfo = DeviceUtils.getDeviceInfo();
// Get geolocation
const location = await DeviceUtils.getGeolocationData();
// Generate fingerprint
const fingerprint = DeviceUtils.generateFingerprint();
// Check browser support
const isSupported = DeviceUtils.isBrowser();
const features = DeviceUtils.getFeatureSupport();Error Handling
import {
PlayeSDKError,
ValidationError,
NetworkError,
AuthenticationError,
GameSessionError,
} from "@workspace/playe-developer-sdk";
try {
await sdk.initializeGameSession(params);
} catch (error) {
if (error instanceof ValidationError) {
console.error("Validation failed:", error.message);
} else if (error instanceof NetworkError) {
console.error("Network error:", error.message);
} else if (error instanceof AuthenticationError) {
console.error("Authentication failed:", error.message);
} else if (error instanceof PlayeSDKError) {
console.error("SDK error:", error.toJSON());
}
}🔒 Security & Integrity
The SDK includes built-in integrity verification to prevent cheating and ensure fair play:
Automatic Features
- Session Integrity: Each game session includes a unique session token and salt
- Game State Hashing: Game states are automatically hashed using SHA-256 with session salt
- Integrity Headers: All authenticated requests include cryptographic integrity headers
- Retry Logic: Failed requests due to integrity issues are automatically retried with fresh headers
How It Works
- Session Initialization: SDK receives session token and salt from server
- State Hashing: Game states are canonicalized and hashed with session salt
- Request Signing: Integrity headers are built with timestamp, nonce, and session token
- Server Validation: Server verifies hashes and headers to detect tampering
Manual Verification (Advanced)
// Manually validate game session
const validation = await sdk.validateGameSession({
clientChecksum: "calculated-checksum",
stateSnapshot: currentGameState,
timingData: { avgResponseTime: 250 },
behaviorMetrics: { clicksPerSecond: 5.2 },
});
if (!validation.isValid) {
console.log("Validation issues:", validation.validationIssues);
}🧪 Testing & Development
Testing
// Create a test game session for development
const testSession = await sdk.createTestGameSession({
testConfig: {
mockCampaign: true,
mockPlayers: 10,
testScenario: "leaderboard",
},
});
console.log("Test session created:", testSession.testSessionId);Debug Mode
Enable debug mode to see detailed logging:
const sdk = createPlayeSDK({
apiBaseUrl: "https://api.playe.com",
enableDebugMode: true, // This will log all API calls, integrity operations, and responses
});URL Requirements
For initializeGameSession() to work, page URL must include a sessionId query parameter:
https://yourgame.com/play?sessionId=abc123-def456-ghi789The SDK will automatically extract this sessionId and initialize session.
📚 Examples
Browser Example
The examples/browser-example.html provides a complete integration example with:
- SDK initialization and configuration
- Session management (initialize, start, update, complete)
- Progress tracking with integrity verification
- Leaderboard fetching and display
- Error handling and recovery
- Debug mode logging
- Device fingerprinting
Flappy Bird Example
The examples/flappy-bird.html provides a complete game integration example with:
- Player eligibility validation (attempts remaining, campaign status)
- Game session initialization with SDK
- Real-time progress tracking
- Score submission with completion data
- Graceful fallback to demo mode if SDK unavailable
- Responsive game canvas with mobile support
🔄 Migration Guide
Migrating from v0.x to v1.x
Breaking Changes
- SDK Initialization
// v0.x
import { PlayeDeveloperSDK } from 'playe-developer-sdk';
const sdk = new PlayeDeveloperSDK(config);
// v1.x
import { createPlayeSDK } from 'playe-developer-sdk';
const sdk = createPlayeSDK(config);- Method Signatures
// v0.x - Callback-based
sdk.initializeGameSession((error, session) => {
if (error) handleError(error);
else handleSuccess(session);
});
// v1.x - Promise-based
try {
const session = await sdk.initializeGameSession();
handleSuccess(session);
} catch (error) {
handleError(error);
}🚨 Error Handling
Error Types
// Base SDK error
PlayeSDKError {
name: string;
message: string;
originalError?: Error;
context?: string;
timestamp: string;
}
// Specific error types
ValidationError extends PlayeSDKError; // Validation failures
NetworkError extends PlayeSDKError; // Network issues
AuthenticationError extends PlayeSDKError; // Authentication failures
GameSessionError extends PlayeSDKError; // Session-specific errorsError Recovery
// Enable debug mode for detailed error information
const sdk = createPlayeSDK({
apiBaseUrl: 'https://api.playe.com',
enableDebugMode: true,
retryAttempts: 3, // Configure retry behavior
timeoutMs: 30000, // Configure timeout
});🔧 Troubleshooting
Common Issues
"No sessionId found in URL" Error
Problem: Getting an error when calling initializeGameSession().
Solution: Ensure your game URL includes a sessionId query parameter:
https://yourgame.com/play?sessionId=abc123-def456-ghi789Network/Timeout Errors
Problem: API calls failing with network errors.
Solutions:
- Check API endpoint configuration
- Verify API key is correct
- Check network connectivity
- Increase timeout for slow networks
Integrity Validation Failures
Problem: Game completion failing with integrity validation errors.
Solutions:
- Ensure game state is valid and serializable
- Check timing data is reasonable
- Use debug mode to inspect requests
🤝 Contributing
We welcome contributions to the Playe Developer SDK!
Development Setup
# Clone repository
git clone https://github.com/playe/playe.git
cd playe
# Install dependencies
pnpm install
# Build SDK
pnpm --filter playe-developer-sdk build
# Run tests
pnpm --filter playe-developer-sdk testCode Guidelines
- Follow TypeScript best practices
- Add tests for new functionality
- Update documentation as needed
- Ensure all tests pass
📄 License
MIT License - see LICENSE file for details.
Copyright (c) 2024 Playe
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
