Games API
The Games API manages game sessions, scoring, progression, and the demo system in PadawanForge.
Base Paths
/api/game-sessions/- Game session management/api/sessions/- Session lifecycle operations/api/demo/- Demo system for anonymous users
Game Sessions
List Game Sessions
GET /api/game-sessions
Authentication: Required
Query Parameters:
page(optional) - Page number (default: 1)limit(optional) - Items per page (default: 20)status(optional) - Filter by status:active,completed,abandoneddifficulty(optional) - Filter by difficulty:easy,medium,hard
Response:
{
"items": [
{
"id": "session_uuid",
"playerId": "player_uuid",
"status": "completed",
"difficulty": "medium",
"startTime": "2024-01-20T15:00:00Z",
"endTime": "2024-01-20T15:07:00Z",
"duration": 420,
"score": 850,
"correctAnswers": 12,
"totalQuestions": 15,
"accuracy": 0.8,
"bestStreak": 8,
"experienceGained": 75
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 45,
"pages": 3
}
}
Get Game Session
GET /api/game-sessions/[id]
Authentication: Required
Parameters:
id- Game session UUID
Response:
{
"id": "session_uuid",
"playerId": "player_uuid",
"status": "completed",
"difficulty": "medium",
"startTime": "2024-01-20T15:00:00Z",
"endTime": "2024-01-20T15:07:00Z",
"duration": 420,
"score": 850,
"correctAnswers": 12,
"totalQuestions": 15,
"accuracy": 0.8,
"bestStreak": 8,
"streakMultiplier": 1.6,
"experienceGained": 75,
"statements": [
{
"id": "stmt_1",
"text": "The Great Wall of China is visible from space.",
"correctAnswer": false,
"playerAnswer": false,
"isCorrect": true,
"timeSpent": 3.2,
"difficulty": "medium",
"category": "history",
"points": 100
}
],
"progressData": {
"questionsAnswered": 15,
"timeRemaining": 0,
"currentStreak": 0,
"hotStreakActive": false,
"coldStreakActive": false
}
}
Session Management
Create Session
POST /api/sessions/create
Authentication: Required
Request Body:
{
"difficulty": "easy" | "medium" | "hard",
"duration": 420,
"categories": ["history", "science", "literature"],
"customSettings": {
"enableHints": true,
"timerVisible": true,
"streakBonuses": true
}
}
Response:
{
"success": true,
"data": {
"sessionId": "session_uuid",
"duration": 420,
"difficulty": "medium",
"startTime": "2024-01-20T15:00:00Z",
"statements": [
{
"id": "stmt_1",
"text": "Water boils at 100Β°C at sea level.",
"difficulty": "easy",
"category": "science"
}
]
}
}
Complete Session
POST /api/sessions/[id]/complete
Authentication: Required
Parameters:
id- Session UUID
Request Body:
{
"answers": [
{
"statementId": "stmt_1",
"answer": true,
"timeSpent": 3.2
},
{
"statementId": "stmt_2",
"answer": false,
"timeSpent": 2.8
}
],
"endTime": "2024-01-20T15:07:00Z",
"finalScore": 850
}
Response:
{
"success": true,
"data": {
"sessionId": "session_uuid",
"finalScore": 850,
"accuracy": 0.8,
"correctAnswers": 12,
"totalQuestions": 15,
"bestStreak": 8,
"experienceGained": 75,
"levelUp": false,
"achievements": [
{
"id": "accuracy_master",
"name": "Accuracy Master",
"description": "Achieve 80% accuracy in a session"
}
],
"leaderboardPosition": 15
}
}
Restore Session
POST /api/sessions/[id]/restore
Authentication: Required
Parameters:
id- Session UUID
Response:
{
"success": true,
"data": {
"sessionId": "session_uuid",
"progress": {
"questionsAnswered": 8,
"timeRemaining": 200,
"currentScore": 560,
"currentStreak": 4
},
"nextStatements": [
{
"id": "stmt_9",
"text": "Shakespeare wrote Romeo and Juliet.",
"difficulty": "medium",
"category": "literature"
}
]
}
}
Cleanup Sessions
POST /api/sessions/cleanup
Authentication: Admin required
Response:
{
"success": true,
"data": {
"cleanedSessions": 150,
"cleanupType": "abandoned_sessions",
"olderThan": "2024-01-15T00:00:00Z"
}
}
Demo System
Create Demo Session
POST /api/demo/session
No authentication required
Request Body:
{
"difficulty": "easy" | "medium" | "hard",
"preferredCategories": ["science", "history"]
}
Response:
{
"success": true,
"data": {
"sessionId": "demo_session_uuid",
"guestToken": "guest_token",
"expiresAt": "2024-01-21T15:00:00Z",
"difficulty": "medium",
"maxDuration": 420,
"remainingDemoTime": 3600,
"canConvert": true
}
}
Get Demo Session
GET /api/demo/[sessionId]
Authentication: Guest token required
Parameters:
sessionId- Demo session UUID
Response:
{
"sessionId": "demo_session_uuid",
"status": "active",
"progress": {
"gamesPlayed": 3,
"bestScore": 720,
"totalExperience": 125,
"timeRemaining": 3200
},
"stats": {
"accuracy": 0.75,
"averageTime": 2.5,
"bestStreak": 6
},
"expiresAt": "2024-01-21T15:00:00Z",
"canConvert": true
}
Generate Demo Content
POST /api/demo/[sessionId]/generate
Authentication: Guest token required
Request Body:
{
"category": "science",
"difficulty": "medium",
"count": 10
}
Response:
{
"success": true,
"data": {
"statements": [
{
"id": "demo_stmt_1",
"text": "Light travels faster than sound.",
"category": "science",
"difficulty": "easy"
}
],
"sessionUpdated": "2024-01-20T15:15:00Z"
}
}
Complete Demo Session
POST /api/demo/[sessionId]/complete
Authentication: Guest token required
Request Body:
{
"answers": [
{
"statementId": "demo_stmt_1",
"answer": true,
"timeSpent": 2.5
}
],
"finalScore": 650
}
Response:
{
"success": true,
"data": {
"score": 650,
"accuracy": 0.8,
"experienceGained": 45,
"newBestScore": true,
"conversionOffer": {
"available": true,
"benefitsPreserved": ["experience", "best_scores", "achievements"],
"additionalBenefits": ["permanent_progress", "social_features", "advanced_customization"]
}
}
}
Convert Demo to Account
POST /api/demo/convert
Authentication: Guest token required
Request Body:
{
"username": "NewPlayer",
"email": "player@example.com",
"oauthProvider": "google",
"oauthCode": "oauth_authorization_code"
}
Response:
{
"success": true,
"data": {
"playerId": "new_player_uuid",
"preservedData": {
"experience": 125,
"bestScore": 720,
"gamesPlayed": 3,
"achievements": ["first_game", "accuracy_novice"]
},
"sessionToken": "full_account_session_token",
"redirectTo": "/dashboard"
}
}
Demo Analytics
GET /api/demo/analytics
Authentication: Admin required
Query Parameters:
startDate(optional) - Start date for analyticsendDate(optional) - End date for analyticsgroupBy(optional) - Group by:day,week,month
Response:
{
"summary": {
"totalDemoSessions": 1250,
"conversionRate": 0.15,
"averageSessionDuration": 380,
"popularCategories": ["science", "history", "literature"]
},
"metrics": [
{
"date": "2024-01-20",
"demoSessions": 45,
"conversions": 7,
"averageScore": 680,
"dropoffPoints": {
"registration": 0.3,
"firstGame": 0.1,
"secondGame": 0.05
}
}
]
}
Scoring System
Score Calculation
- Base Points: 100 per correct answer
- Time Bonus: Faster answers get up to 50% bonus
- Streak Multiplier: Hot streaks multiply points by up to 2x
- Difficulty Bonus: Harder questions give 25-50% more points
Streak System
- Hot Streak: 3+ consecutive correct answers
- Cold Streak: 3+ consecutive incorrect answers
- Streak Multiplier: Increases with streak length (max 2x)
- Streak Recovery: Cold streaks reduce multiplier
Experience System
- Base XP: 5 XP per correct answer
- Completion Bonus: 25 XP for finishing session
- Performance Bonus: Up to 50 XP for high accuracy
- Level Up: Every 1000 XP increases level
Error Responses
Session Not Found
{
"error": "Session not found",
"details": "No active session found with the provided ID"
}
Demo Expired
{
"error": "Demo session expired",
"details": "Demo sessions are limited to 24 hours",
"canCreateNew": true
}
Invalid Answers
{
"error": "Invalid answer format",
"details": "Answer must be true or false"
}
Session Already Completed
{
"error": "Session already completed",
"details": "Cannot modify completed session"
}
Rate Limits
- Session creation: 10 per hour per user
- Demo sessions: 5 per IP per hour
- Session completion: No limit (expected behavior)
- Demo conversion: 3 attempts per demo session
Implementation Notes
- Session Persistence: Active sessions stored in memory with periodic database saves
- Demo Isolation: Demo data isolated from main player data until conversion
- Anti-Cheat: Server-side validation of answer timing and patterns
- Progressive Difficulty: AI adjusts statement difficulty based on player performance
- Data Recovery: Sessions can be restored if interrupted (5-minute window)
Training Game System API
The Training Game System provides a database-backed, extensible game platform with support for multiple game types through pluggable game engines.
Base Paths
/api/games/- Public training game endpoints/api/admin/game-topics/- Admin topic management/api/admin/game-challenges/- Admin challenge management/api/admin/game-analytics/- Analytics and reporting
Architecture
- Game Types: Pluggable game engines (currently:
true-false-cognitive) - Storage: D1 database for persistent content
- Caching: KV storage for active session data (24-hour TTL)
- Guest Support: Anonymous play without authentication
- Admin Control: Full CRUD interface with
admin.gamespermission
Training Game Topics
List Game Topics
GET /api/games/topics
No authentication required
Query Parameters:
game_type(optional) - Filter by game type (e.g.,true-false-cognitive)difficulty(optional) - Filter by difficulty level
Response:
{
"success": true,
"data": {
"topics": [
{
"id": 1,
"name": "Physics",
"description": "Physical laws and phenomena",
"icon": "βοΈ",
"game_types": ["true-false-cognitive"],
"difficulty_range": ["basic", "intermediate", "advanced"],
"is_active": true,
"created_at": "2024-01-20T10:00:00Z",
"updated_at": "2024-01-20T10:00:00Z"
}
]
}
}
Training Game Sessions
Create Training Session
POST /api/games/sessions
No authentication required (supports guest sessions)
Request Body:
{
"game_type": "true-false-cognitive",
"topic_id": 1,
"time_limit_seconds": 420,
"total_challenges": 40,
"player_uuid": "optional-player-uuid"
}
Response:
{
"success": true,
"data": {
"session": {
"id": 1,
"session_id": "abc123xyz",
"game_type": "true-false-cognitive",
"topic_id": 1,
"player_uuid": null,
"total_questions": 40,
"current_question": 0,
"correct_answers": 0,
"start_time": "2024-01-20T15:00:00Z",
"time_limit_seconds": 420,
"status": "active",
"created_at": "2024-01-20T15:00:00Z",
"updated_at": "2024-01-20T15:00:00Z"
}
}
}
Get Training Session
GET /api/games/sessions
No authentication required
Query Parameters:
session_id- Session identifier (required)
Response:
{
"success": true,
"data": {
"session": {
"id": 1,
"session_id": "abc123xyz",
"game_type": "true-false-cognitive",
"topic_id": 1,
"total_questions": 40,
"current_question": 15,
"correct_answers": 12,
"status": "active",
"final_score": null,
"accuracy_percentage": null
}
}
}
Training Game Challenges
Get Next Challenge
GET /api/games/challenges/[sessionId]
No authentication required
Parameters:
sessionId- Session identifier
Response:
{
"success": true,
"data": {
"challenge": {
"id": 42,
"prompt": "Sound travels faster through water than air.",
"difficulty": "basic"
}
}
}
Notes:
- Challenge answers are NEVER sent to client
- Server-side validation only
- Challenges are selected randomly, excluding previously shown
- Session tracks shown challenges to prevent repeats
Training Game Answers
Submit Answer
POST /api/games/answers
No authentication required
Request Body:
{
"session_id": "abc123xyz",
"challenge_id": 42,
"player_answer": "true",
"time_taken_ms": 3500
}
Response:
{
"success": true,
"data": {
"is_correct": true,
"points_awarded": 10,
"feedback": "Correct! Sound travels about 4x faster in water than air.",
"session_complete": false
}
}
Session Completion Response:
{
"success": true,
"data": {
"is_correct": true,
"points_awarded": 10,
"feedback": "Well done!",
"session_complete": true,
"final_results": {
"final_score": 850,
"accuracy_percentage": 87.5,
"performance_metrics": {
"correct_count": 35,
"total_questions": 40,
"avg_time_ms": 4200,
"time_bonus": 50
}
}
}
}
Admin - Topic Management
List Topics (Admin)
GET /api/admin/game-topics
Authentication: Admin required (admin.games permission)
Response:
{
"success": true,
"data": {
"topics": [
{
"id": 1,
"name": "Physics",
"description": "Physical laws and phenomena",
"icon": "βοΈ",
"game_types": ["true-false-cognitive"],
"difficulty_range": ["basic", "intermediate", "advanced"],
"is_active": true,
"created_at": "2024-01-20T10:00:00Z",
"updated_at": "2024-01-20T10:00:00Z"
}
]
}
}
Create Topic
POST /api/admin/game-topics
Authentication: Admin required (admin.games permission)
Request Body:
{
"name": "Mathematics",
"description": "Mathematical concepts and theorems",
"icon": "π’",
"game_types": ["true-false-cognitive"],
"difficulty_range": ["basic", "intermediate", "advanced"]
}
Response:
{
"success": true,
"message": "Topic created successfully"
}
Update Topic
PUT /api/admin/game-topics/[id]
Authentication: Admin required (admin.games permission)
Parameters:
id- Topic ID
Request Body:
{
"name": "Advanced Physics",
"description": "Complex physical phenomena",
"icon": "βοΈ",
"game_types": ["true-false-cognitive", "multiple-choice"],
"difficulty_range": ["intermediate", "advanced"],
"is_active": true
}
Response:
{
"success": true,
"message": "Topic updated successfully"
}
Delete Topic (Soft Delete)
DELETE /api/admin/game-topics/[id]
Authentication: Admin required (admin.games permission)
Parameters:
id- Topic ID
Response:
{
"success": true,
"message": "Topic deleted successfully"
}
Notes:
- Topics are soft-deleted (is_active = 0)
- Associated challenges remain in database
- Can be reactivated by setting is_active = 1
Admin - Challenge Management
List Challenges (Admin)
GET /api/admin/game-challenges
Authentication: Admin required (admin.games permission)
Query Parameters:
topic_id(optional) - Filter by topic
Response:
{
"success": true,
"data": {
"challenges": [
{
"id": 42,
"game_type": "true-false-cognitive",
"topic_id": 1,
"prompt": "Sound travels faster through water than air.",
"difficulty": "basic",
"challenge_data": {
"answer": true,
"explanation": "Sound travels about 4x faster in water due to higher density."
},
"is_active": true,
"created_at": "2024-01-20T10:00:00Z",
"updated_at": "2024-01-20T10:00:00Z"
}
]
}
}
Create Challenge
POST /api/admin/game-challenges
Authentication: Admin required (admin.games permission)
Request Body:
{
"game_type": "true-false-cognitive",
"topic_id": 1,
"prompt": "The speed of light is constant in all reference frames.",
"difficulty": "advanced",
"challenge_data": {
"answer": true,
"explanation": "This is a fundamental postulate of Einstein's theory of special relativity."
}
}
Response:
{
"success": true,
"message": "Challenge created successfully"
}
Update Challenge
PUT /api/admin/game-challenges/[id]
Authentication: Admin required (admin.games permission)
Parameters:
id- Challenge ID
Request Body:
{
"prompt": "Light speed is constant in vacuum in all reference frames.",
"difficulty": "advanced",
"challenge_data": {
"answer": true,
"explanation": "Updated explanation with more detail..."
},
"is_active": true
}
Response:
{
"success": true,
"message": "Challenge updated successfully"
}
Delete Challenge (Soft Delete)
DELETE /api/admin/game-challenges/[id]
Authentication: Admin required (admin.games permission)
Parameters:
id- Challenge ID
Response:
{
"success": true,
"message": "Challenge deleted successfully"
}
Admin - Analytics
Get Game Analytics
GET /api/admin/game-analytics
Authentication: Admin required (admin.games permission)
Response:
{
"success": true,
"data": {
"metrics": {
"total_sessions": 1250,
"completed_sessions": 980,
"avg_score": 745.5,
"avg_accuracy": 78.3,
"completion_rate": 78.4
},
"popular_topics": [
{
"topic_id": 1,
"topic_name": "Physics",
"session_count": 340
},
{
"topic_id": 5,
"topic_name": "Biology",
"session_count": 285
}
],
"recent_sessions": [
{
"id": 125,
"session_id": "xyz789",
"game_type": "true-false-cognitive",
"topic_name": "Physics",
"player_uuid": null,
"final_score": 850,
"accuracy_percentage": 87.5,
"status": "completed",
"created_at": "2024-01-20T14:30:00Z"
}
]
}
}
Training Game Scoring System
True/False Cognitive Game
Base Points (by difficulty):
- Basic: 10 points
- Intermediate: 20 points
- Advanced: 30 points
Time Bonus:
- Target: 5 seconds per question
- Bonus: Up to 50 points per question for fast answers
- Formula:
Math.min((5000 - avgTimeMs) / 100 * totalQuestions, totalQuestions * 50)
Final Score Calculation:
Final Score = Total Points + Time Bonus
Accuracy = (Correct Answers / Total Questions) * 100
Example:
- 40 questions, 35 correct (all basic difficulty)
- Total Points: 35 Γ 10 = 350
- Average time: 3.5 seconds (3500ms)
- Time Bonus: ((5000 - 3500) / 100) Γ 40 = 60
- Final Score: 350 + 60 = 410
- Accuracy: (35 / 40) Γ 100 = 87.5%
Game Engine Architecture
The training game system uses a pluggable GameEngine interface:
GameEngine Interface
interface GameEngine {
// Generate next challenge for session
generateChallenge(session, previousChallenges): Promise<GameChallenge>
// Validate player answer
validateAnswer(challenge, playerAnswer): ValidationResult
// Calculate final score
calculateScore(session, answers): ScoreResult
// Render challenge for client (excludes answer)
renderChallenge(challenge): RenderData
}
Current Implementations
TrueFalseCognitiveEngine- True/false statement verification
Adding New Game Types
- Create engine implementing
GameEngine - Register in
initializeGameEngines(db) - Create UI component for challenge rendering
- Add topics with new game_type
- Add challenges with game-specific challenge_data
See Training Game System Documentation for detailed guide.
Error Responses
Topic Not Found
{
"success": false,
"error": "Topic not found"
}
Session Not Found
{
"success": false,
"error": "Session not found"
}
Invalid Game Type
{
"success": false,
"error": "Invalid game type. Supported types: true-false-cognitive"
}
No Challenges Available
{
"success": false,
"error": "No more challenges available for this topic"
}
Permission Denied
{
"success": false,
"error": "Forbidden",
"message": "Insufficient permissions. Required: admin.games"
}
Rate Limits
- Public endpoints: No rate limits (guest-friendly)
- Admin endpoints: 100 requests per minute per admin
- Session creation: Unlimited (supports high-volume guest play)
- Challenge generation: No limit (expected behavior)
Implementation Notes
- Server-Side Validation: All answer validation happens server-side; correct answers never sent to client
- KV Caching: Active sessions cached in KV with 24-hour TTL for fast access
- Soft Deletes: Topics and challenges use
is_activeflag for soft deletion - Random Selection: Challenges selected via
ORDER BY RANDOM()with exclusion list - Guest Sessions: Full functionality without authentication; optional player_uuid for registered users
- Database Indexes: Optimized queries with indexes on topic_id, game_type, and status