export type GameState = | 'LANDING' | 'CREATING' | 'GENERATING' | 'EDITING' | 'LOBBY' | 'COUNTDOWN' | 'QUESTION' | 'REVEAL' | 'SCOREBOARD' | 'PODIUM' | 'DISCONNECTED' | 'WAITING_TO_REJOIN' | 'HOST_RECONNECTED'; export type GameRole = 'HOST' | 'CLIENT'; export interface AnswerOption { text: string; isCorrect: boolean; shape: 'triangle' | 'diamond' | 'circle' | 'square'; color: 'red' | 'blue' | 'yellow' | 'green'; reason?: string; // Explanation for why this answer is correct or incorrect } export interface Question { id: string; text: string; options: AnswerOption[]; timeLimit: number; // in seconds } export interface GameConfig { shuffleQuestions: boolean; shuffleAnswers: boolean; hostParticipates: boolean; streakBonusEnabled: boolean; streakThreshold: number; streakMultiplier: number; comebackBonusEnabled: boolean; comebackBonusPoints: number; penaltyForWrongAnswer: boolean; penaltyPercent: number; firstCorrectBonusEnabled: boolean; firstCorrectBonusPoints: number; } export const DEFAULT_GAME_CONFIG: GameConfig = { shuffleQuestions: false, shuffleAnswers: false, hostParticipates: true, streakBonusEnabled: false, streakThreshold: 3, streakMultiplier: 1.1, comebackBonusEnabled: false, comebackBonusPoints: 50, penaltyForWrongAnswer: false, penaltyPercent: 25, firstCorrectBonusEnabled: false, firstCorrectBonusPoints: 50, }; export interface Quiz { title: string; questions: Question[]; config?: GameConfig; } export type QuizSource = 'manual' | 'ai_generated'; export interface SavedQuiz extends Quiz { id: string; source: QuizSource; aiTopic?: string; createdAt: string; updatedAt: string; config?: GameConfig; } export interface QuizListItem { id: string; title: string; source: QuizSource; aiTopic?: string; questionCount: number; createdAt: string; updatedAt: string; } export interface ProcessedDocument { type: 'native' | 'text'; content: string | Buffer; mimeType?: string; } export interface GenerateQuizOptions { topic?: string; questionCount?: number; documents?: ProcessedDocument[]; } export interface PointsBreakdown { basePoints: number; streakBonus: number; comebackBonus: number; firstCorrectBonus: number; penalty: number; total: number; } export interface Player { id: string; name: string; score: number; previousScore: number; streak: number; lastAnswerCorrect: boolean | null; selectedShape: 'triangle' | 'diamond' | 'circle' | 'square' | null; pointsBreakdown: PointsBreakdown | null; isBot: boolean; avatarSeed: number; color: string; } // Network Types export type NetworkMessage = | { type: 'JOIN'; payload: { name: string; reconnect?: boolean; previousId?: string } } | { type: 'WELCOME'; payload: { playerId: string; quizTitle: string; players: Player[]; gameState?: GameState; score?: number; streak?: number; hasAnswered?: boolean; lastAnswerCorrect?: boolean | null; lastPointsEarned?: number; selectedShape?: 'triangle' | 'diamond' | 'circle' | 'square' | null; currentQuestionIndex?: number; totalQuestions?: number; questionText?: string; options?: AnswerOption[]; correctShape?: string; timeLeft?: number; } } | { type: 'PLAYER_JOINED'; payload: { player: Player } } | { type: 'GAME_START'; payload: {} } | { type: 'START_COUNTDOWN'; payload: { duration: number } } | { type: 'QUESTION_START'; payload: { totalQuestions: number; currentQuestionIndex: number; timeLimit: number; correctShape: string; questionText: string; options: AnswerOption[]; } } | { type: 'ANSWER'; payload: { playerId: string; isCorrect: boolean; selectedShape: 'triangle' | 'diamond' | 'circle' | 'square' } } | { type: 'RESULT'; payload: { isCorrect: boolean; scoreAdded: number; newScore: number; breakdown: PointsBreakdown } } | { type: 'TIME_SYNC'; payload: { timeLeft: number } } | { type: 'TIME_UP'; payload: {} } | { type: 'SHOW_SCOREBOARD'; payload: { players: Player[] } } | { type: 'GAME_OVER'; payload: { players: Player[] } };