Training Game System

The Training Game System is a database-backed, extensible cognitive training platform that allows players to learn through interactive challenges across multiple topics and game types.

Overview

The system provides:

  • Database-driven content - All topics and challenges stored in D1
  • Multiple game types - Extensible architecture via GameEngine interface
  • Admin management - Full CRUD interface for content management
  • Performance tracking - Session history, scores, and analytics
  • Guest support - Anonymous play without registration

Architecture

Components

User Interface (React)

Game Container (State Management)

Game Play Area (Gameplay Logic)

Challenge Renderer (Dynamic UI)

Game Engine (Validation & Scoring)

D1 Database (Content Storage)

Database Schema

Tables

  1. game_topics - Subject areas for challenges

    • id, name, description, icon
    • game_types (JSON array)
    • difficulty_range (JSON array)
    • is_active, timestamps
  2. game_challenges - Individual questions/challenges

    • id, game_type, topic_id
    • prompt, difficulty
    • challenge_data (JSON - answer, explanation)
    • is_active, timestamps
  3. game_training_sessions - Player game sessions

    • id, session_id, game_type
    • player_uuid (nullable for guests)
    • topic_id, progress tracking
    • final_score, accuracy_percentage
    • status (‘active’ | ‘completed’ | ‘abandoned’)
  4. game_answers - Answer history

    • id, session_id, challenge_id
    • player_answer, is_correct
    • time_taken_ms, points_awarded

Game Engine System

The GameEngine interface enables multiple game types:

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

Future Implementations:

  • MultipleChoiceEngine - Multiple choice questions
  • MemoryMatchEngine - Memory matching games
  • WordPuzzleEngine - Word-based challenges

API Endpoints

Public Endpoints

GET /api/games/topics

Get available game topics with filtering.

Query Parameters:

  • game_type (optional) - Filter by game type
  • difficulty (optional) - Filter by difficulty

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
      }
    ]
  }
}

POST /api/games/sessions

Create a new game session.

Request Body:

{
  "game_type": "true-false-cognitive",
  "topic_id": 1,
  "time_limit_seconds": 420,
  "total_challenges": 40,
  "player_uuid": "optional-uuid"
}

Response:

{
  "success": true,
  "data": {
    "session": {
      "id": 1,
      "session_id": "abc123",
      "game_type": "true-false-cognitive",
      "topic_id": 1,
      "total_questions": 40,
      "current_question": 0,
      "status": "active"
    }
  }
}

GET /api/games/challenges/:sessionId

Get next challenge for session.

Response:

{
  "success": true,
  "data": {
    "challenge": {
      "id": 42,
      "prompt": "Sound travels faster through water than air.",
      "difficulty": "basic"
    }
  }
}

POST /api/games/answers

Submit answer and get validation.

Request Body:

{
  "session_id": "abc123",
  "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.",
    "session_complete": false
  }
}

Admin Endpoints

All admin endpoints require admin.games permission.

Topics Management

  • POST /api/admin/game-topics - Create topic
  • PUT /api/admin/game-topics/:id - Update topic
  • DELETE /api/admin/game-topics/:id - Delete topic (soft)

Challenges Management

  • GET /api/admin/game-challenges?topic_id=X - List challenges
  • POST /api/admin/game-challenges - Create challenge
  • PUT /api/admin/game-challenges/:id - Update challenge
  • DELETE /api/admin/game-challenges/:id - Delete challenge (soft)

Analytics

  • GET /api/admin/game-analytics - Get statistics

User Interface

Player Experience

1. Topic Selection (/training)

  • Browse 17 available topics
  • See topic icons, descriptions, difficulty levels
  • Select topic to start

2. Ready Screen

  • Shows question count, time limit
  • Instructions and rules
  • Start game button

3. Gameplay

  • Timer - Countdown from 7 minutes
  • Progress - Question counter (e.g., 15/40)
  • Score - Real-time score display
  • Challenge - Question with difficulty badge
  • Actions - TRUE/FALSE buttons

4. Completion

  • Final score with confetti animation
  • Accuracy percentage
  • Performance metrics (avg time, time bonus)
  • Actions - Play again, choose new topic, sign up

Admin Interface

Topics Tab (/admin/game-management)

  • Table view - All topics with icons, game types, difficulties
  • Create - Form with name, description, icon, settings
  • Edit - Inline editing with dialog
  • Delete - Soft delete with confirmation

Challenges Tab

  • Filter - Dropdown to filter by topic
  • Table view - Prompt, difficulty, answer, status
  • Create - Comprehensive form for new challenges
  • Edit - Modify any challenge field
  • Delete - Soft delete with confirmation

Analytics Tab

  • Metrics Cards - Sessions, avg score, accuracy, completion rate
  • Popular Topics - Top 5 most played
  • Recent Sessions - Last 10 with details

Scoring System

Base Points (True/False Cognitive)

  • 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 / Total) * 100

Adding New Game Types

1. Create Game Engine

// src/lib/game-engine/multiple-choice-engine.ts
export class MultipleChoiceEngine implements GameEngine {
  async generateChallenge(session, previousChallenges) {
    // Query database for multiple-choice questions
    // Return challenge with options in challenge_data
  }

  validateAnswer(challenge, playerAnswer) {
    // Check if selected option is correct
    return { is_correct, points_awarded, feedback }
  }

  calculateScore(session, answers) {
    // Calculate score with multiple-choice rules
    return { final_score, accuracy_percentage, performance_metrics }
  }

  renderChallenge(challenge) {
    // Return prompt + options (exclude correct answer)
    return { id, prompt, options, difficulty }
  }
}

2. Register Engine

// src/lib/game-engine/index.ts
import { MultipleChoiceEngine } from './multiple-choice-engine';

export function initializeGameEngines(db: D1Database) {
  gameEngineRegistry.register('true-false-cognitive', new TrueFalseCognitiveEngine(db));
  gameEngineRegistry.register('multiple-choice', new MultipleChoiceEngine(db));
}

3. Create UI Component

// src/components/game/challenges/multiple-choice-challenge.tsx
export function MultipleChoiceChallenge({ challenge, onAnswer }) {
  return (
    <div>
      <h2>{challenge.prompt}</h2>
      {challenge.options.map(option => (
        <button onClick={() => onAnswer(option.id)}>
          {option.text}
        </button>
      ))}
    </div>
  );
}

4. Register in Renderer

// src/components/game/challenge-renderer.tsx
const challengeComponents = {
  'true-false-cognitive': TrueFalseChallenge,
  'multiple-choice': MultipleChoiceChallenge, // Add new type
};

5. Add Topics

Use admin interface to:

  1. Create topic with game_types: ["multiple-choice"]
  2. Add challenges with game_type: "multiple-choice"
  3. Set challenge_data with options array

Data Management

Seeding Challenges

Use the seeding script to import challenges:

# Create challenges from data source
bun run scripts/seed-game-challenges.ts

# Apply migration
bun run db:migrate

Bulk Import

INSERT INTO game_challenges (game_type, topic_id, prompt, difficulty, challenge_data, is_active, created_at, updated_at)
SELECT
  'true-false-cognitive',
  (SELECT id FROM game_topics WHERE name = 'Physics'),
  statement_text,
  'basic',
  json_object('answer', is_true, 'explanation', explanation_text),
  1,
  datetime('now'),
  datetime('now')
FROM external_data_source;

Performance Optimization

KV Caching

Active sessions are cached in KV for fast access:

  • Key: game_session_{sessionId}
  • Value: Session data + previousChallenges array
  • TTL: 24 hours

Database Indexes

  • idx_game_challenges_topic - Fast topic filtering
  • idx_game_challenges_type - Fast game type filtering
  • idx_game_sessions_status - Active session queries

Query Optimization

  • Use RANDOM() with exclusion list for challenge selection
  • Limit to 40 challenges per session
  • Batch analytics queries for admin dashboard

Security

Guest Sessions

  • Temporary session IDs (nanoid)
  • No persistent player data
  • 24-hour expiration

Admin Protection

  • RBAC with admin.games permission
  • All admin endpoints use withAdminPermission middleware
  • Soft deletes preserve data integrity

Answer Validation

  • Server-side validation only
  • Challenge answers never sent to client
  • Validation done via GameEngine

Monitoring

Analytics Tracked

  • Total sessions (all time)
  • Completed sessions
  • Average score
  • Average accuracy
  • Popular topics
  • Recent session history

Session States

  • active - Currently playing
  • completed - Finished successfully
  • abandoned - Timed out or quit

Migration from Demo System

The training game system runs parallel to the existing demo system:

FeatureDemo SystemTraining Game System
Route/demo/training
StorageKV (hardcoded)D1 (database)
Content40 statements54+ challenges (expandable)
Admin UILimitedFull CRUD
Game TypesTrue/False onlyExtensible
AnalyticsBasicComprehensive

Both systems coexist - no breaking changes to demo system.

Troubleshooting

Challenge Not Loading

  • Check session is active: SELECT * FROM game_training_sessions WHERE session_id = ?
  • Verify challenges exist: SELECT COUNT(*) FROM game_challenges WHERE topic_id = ?
  • Check previousChallenges list isn’t excluding all challenges

Score Not Calculating

  • Verify answers recorded: SELECT * FROM game_answers WHERE session_id = ?
  • Check GameEngine implementation
  • Review time bonus calculation (cap at 50 points per question)

Admin Permission Denied

  • Verify user has admin.games permission
  • Check role assignments in player_roles table
  • Review permission system in /api/admin/game-* endpoints

Future Enhancements

Planned Features

  • Adaptive Difficulty - AI-adjusted challenge selection
  • Leaderboards - Global and topic-specific rankings
  • Daily Challenges - Featured questions each day
  • Achievements - Unlock badges for milestones
  • Streaks - Consecutive day bonuses
  • Multiplayer - Competitive head-to-head modes

Additional Game Types

  • Multiple Choice
  • Memory Match
  • Word Puzzles
  • Math Challenges
  • Pattern Recognition
  • Code Challenges

Quick Links:

PadawanForge v1.4.2