# Know Foolery - Game Mechanics Documentation ## Overview Know Foolery is a quiz game where players answer questions to earn points within a time-limited session. The game emphasizes strategic thinking through its hint system and attempt limitations. ## Core Game Flow ### 1. Game Session Initialization ``` Player Input: Name → Session Creation → Question Selection → Game Start ``` **Process:** 1. Player enters their name (required) 2. System creates new game session 3. System randomly selects first question 4. 30-minute timer starts 5. Game begins with question display **Validation:** - Player name: 2-50 characters, alphanumeric + spaces - Session uniqueness: One active session per player - Timer initialization: Server-side timestamp ### 2. Question Presentation **Question Structure:** ```typescript interface Question { id: string theme: string // e.g., "Geography", "History", "Science" text: string // The actual question answer: string // Correct answer (case-insensitive) hint: string // Optional hint text difficulty?: number // Future enhancement } ``` **Display Format:** ``` ┌─────────────────────────────────────┐ │ Theme: Geography ⏱️ 28:45 │ ├─────────────────────────────────────┤ │ │ │ What is the capital of France? │ │ │ │ [Your answer here... ] 💡 │ │ │ │ Attempts remaining: 3/3 │ │ Current score: 4 points │ └─────────────────────────────────────┘ ``` ### 3. Answer Submission Process **Player Actions:** 1. **Direct Answer**: Submit answer without hint 2. **Request Hint**: View hint before answering 3. **Skip Question**: Move to next question (future enhancement) **Answer Validation:** ```go // Server-side validation logic func ValidateAnswer(userAnswer, correctAnswer string) bool { // Normalize both answers user := strings.ToLower(strings.TrimSpace(userAnswer)) correct := strings.ToLower(strings.TrimSpace(correctAnswer)) // Exact match if user == correct { return true } // Fuzzy matching (future enhancement) similarity := calculateSimilarity(user, correct) return similarity > 0.85 } ``` ## Scoring System ### Point Values - **Correct without hint**: 2 points - **Correct with hint**: 1 point - **Incorrect answer**: 0 points - **Session timeout**: 0 points for remaining questions ### Scoring Logic ```go type AttemptResult struct { IsCorrect bool UsedHint bool AttemptNum int // 1, 2, or 3 } func CalculateScore(result AttemptResult) int { if !result.IsCorrect { return 0 } if result.UsedHint { return 1 // Reduced score for using hint } return 2 // Full score for direct correct answer } ``` ### Score Tracking ```go type GameSession struct { PlayerName string TotalScore int QuestionsAsked int QuestionsCorrect int HintsUsed int StartTime time.Time EndTime *time.Time IsActive bool } ``` ## Attempt System ### Attempt Rules - **Maximum Attempts**: 3 per question - **Attempt Tracking**: Server-side validation - **Attempt Consequences**: - Attempt 1-3: Normal scoring if correct - After 3 failed attempts: Move to next question automatically ### Attempt Flow ```go type QuestionAttempt struct { SessionID string QuestionID string AttemptNum int // 1, 2, or 3 Answer string IsCorrect bool UsedHint bool Timestamp time.Time } func ProcessAttempt(sessionID, questionID, answer string) AttemptResult { // 1. Validate session is active // 2. Check attempts remaining // 3. Validate answer // 4. Update score if correct // 5. Move to next question if needed } ``` ## Hint System ### Hint Mechanics - **Availability**: One hint per question - **Timing**: Can be requested before any attempt - **Impact**: Reduces maximum score from 2 to 1 points - **Content**: Provides helpful clue without giving away answer ### Hint Implementation ```typescript interface HintRequest { sessionId: string questionId: string } interface HintResponse { hint: string scoreImpact: string // "Using this hint will reduce your score to 1 point" attemptsRemaining: number } ``` ### Hint Examples ```javascript const hintExamples = { question: "What is the capital of France?", hint: "This city is famous for the Eiffel Tower and is located on the Seine River.", question: "Who painted the Mona Lisa?", hint: "This Italian Renaissance artist was also an inventor and scientist.", question: "What is the largest planet in our solar system?", hint: "This gas giant is named after the king of the Roman gods." } ``` ## Time Management ### Session Timer - **Duration**: 30 minutes maximum per session - **Display**: Real-time countdown timer - **Warnings**: Visual alerts at 5 minutes and 1 minute remaining - **Timeout**: Automatic session termination when time expires ### Timer Implementation ```go type SessionTimer struct { SessionID string StartTime time.Time Duration time.Duration // 30 minutes WarningsSent map[int]bool // Track warnings sent } func (t *SessionTimer) TimeRemaining() time.Duration { elapsed := time.Since(t.StartTime) remaining := t.Duration - elapsed if remaining < 0 { return 0 } return remaining } func (t *SessionTimer) IsExpired() bool { return t.TimeRemaining() == 0 } ``` ### Timer Events ```typescript interface TimerEvent { type: 'warning' | 'timeout' timeRemaining: number // seconds message: string } // Timer warnings const timerWarnings = [ { at: 300, message: "5 minutes remaining!" }, // 5 minutes { at: 60, message: "1 minute remaining!" }, // 1 minute { at: 10, message: "10 seconds left!" } // 10 seconds ] ``` ## Question Selection ### Random Selection Algorithm ```go func SelectRandomQuestion(sessionID string, excludeAnswered bool) (*Question, error) { var questions []Question query := db.Question.Query() if excludeAnswered { // Exclude questions already answered in this session answeredIDs := getAnsweredQuestions(sessionID) query = query.Where(question.IDNotIn(answeredIDs...)) } questions, err := query.All(ctx) if err != nil { return nil, err } if len(questions) == 0 { return nil, errors.New("no more questions available") } // Random selection randomIndex := rand.Intn(len(questions)) return &questions[randomIndex], nil } ``` ### Question Difficulty (Future Enhancement) ```go type DifficultyLevel int const ( Easy DifficultyLevel = iota + 1 Medium Hard ) // Adaptive difficulty based on player performance func SelectQuestionByDifficulty(sessionID string, targetDifficulty DifficultyLevel) (*Question, error) { // Implementation for adaptive difficulty // Consider player's success rate, current score, etc. } ``` ## Leaderboard System ### Leaderboard Calculation ```go type LeaderboardEntry struct { PlayerName string Score int QuestionsAnswered int SuccessRate float64 // Percentage of correct answers SessionDuration time.Duration CompletedAt time.Time } func CalculateLeaderboard() ([]LeaderboardEntry, error) { sessions := getCompletedSessions() entries := make([]LeaderboardEntry, 0, len(sessions)) for _, session := range sessions { entry := LeaderboardEntry{ PlayerName: session.PlayerName, Score: session.TotalScore, QuestionsAnswered: session.QuestionsAsked, SuccessRate: float64(session.QuestionsCorrect) / float64(session.QuestionsAsked) * 100, SessionDuration: session.EndTime.Sub(session.StartTime), CompletedAt: *session.EndTime, } entries = append(entries, entry) } // Sort by score (descending), then by completion time (ascending) sort.Slice(entries, func(i, j int) bool { if entries[i].Score == entries[j].Score { return entries[i].CompletedAt.Before(entries[j].CompletedAt) } return entries[i].Score > entries[j].Score }) // Return top 10 if len(entries) > 10 { entries = entries[:10] } return entries, nil } ``` ### Leaderboard Display ``` 🏆 LEADERBOARD Rank | Player | Score | Questions | Success Rate | Duration -----|-----------|-------|-----------|--------------|---------- 1 | Alice | 24 | 14 | 86% | 28m 2 | Bob | 22 | 13 | 85% | 25m 3 | Charlie | 20 | 12 | 83% | 30m 4 | Diana | 18 | 11 | 82% | 22m 5 | Eve | 16 | 10 | 80% | 27m ``` ## Game State Management ### Session States ```go type SessionState int const ( SessionCreated SessionState = iota SessionActive SessionPaused // Future enhancement SessionCompleted SessionTimedOut SessionAbandoned ) type GameSession struct { ID string PlayerName string State SessionState CurrentQuestion *Question Score int // ... other fields } ``` ### State Transitions ``` Created → Active → {Completed, TimedOut, Abandoned} ↓ Paused → Active (future enhancement) ``` ## Anti-Cheating Measures ### Server-Side Validation ```go type SecurityCheck struct { SessionID string QuestionID string ExpectedAnswer string SubmittedAnswer string TimestampSubmit time.Time TimestampShow time.Time IsValid bool Reason string } func ValidateSubmission(check SecurityCheck) bool { // 1. Check minimum time between question show and answer submit minTime := 2 * time.Second if check.TimestampSubmit.Sub(check.TimestampShow) < minTime { check.Reason = "Answer submitted too quickly" return false } // 2. Validate session state session := getSession(check.SessionID) if session.State != SessionActive { check.Reason = "Invalid session state" return false } // 3. Check if question belongs to session if session.CurrentQuestion.ID != check.QuestionID { check.Reason = "Question mismatch" return false } return true } ``` ### Client-Side Integrity ```typescript // Prevent common cheating attempts class GameIntegrity { private questionStartTime: number = 0 onQuestionDisplayed() { this.questionStartTime = Date.now() // Disable browser dev tools (basic deterrent) this.disableDevTools() // Prevent copy-paste in answer input this.disableCopyPaste() } onAnswerSubmit(answer: string) { const timeTaken = Date.now() - this.questionStartTime // Include timing in submission for server validation return { answer, timeTaken, timestamp: Date.now() } } private disableDevTools() { // Basic dev tools detection (not foolproof) const devtools = { open: false, orientation: null } const threshold = 160 setInterval(() => { if (window.outerHeight - window.innerHeight > threshold || window.outerWidth - window.innerWidth > threshold) { console.warn('Developer tools detected') // Log security event } }, 500) } } ``` ## Future Enhancements ### Planned Features 1. **Question Categories**: Filter questions by subject 2. **Difficulty Progression**: Adaptive difficulty based on performance 3. **Multiplayer Mode**: Real-time competition between players 4. **Daily Challenges**: Special themed question sets 5. **Achievement System**: Badges and milestones 6. **Question Contributions**: Player-submitted questions ### Scoring Enhancements 1. **Time Bonus**: Extra points for quick correct answers 2. **Streak Bonus**: Consecutive correct answers bonus 3. **Difficulty Multiplier**: Higher points for harder questions 4. **Perfect Game Bonus**: Bonus for 100% correct rate This game mechanics documentation ensures consistent implementation across all platforms and provides clear guidelines for future enhancements.