Skip to content

About

Open Source Trivia Game that can be self hosted on a local device or home lab. Built with Vue 3, Javascript, CSS , PostgresSQL, and Socket.IO

Topics

Resources

Contributing

Stars

19 stars

Watchers

2 watching

Forks

Repository files navigation

TriviaForge

A production-ready, real-time interactive trivia game platform built with Vue 3, Socket.IO, and PostgreSQL. Designed for educators, event organizers, and trivia enthusiasts with robust connection stability, persistent player sessions, and estimated capacity for 50+ concurrent players.

Latest Release: v5.15.0 - Open-Ended (Short Answer) Questions (see ROADMAP.md for full release history)

Key Highlights

  • 🎯 Production-Ready: Tested with simulated sessions of 50+ concurrent players
  • ⚡ Persistent Player Sessions: Dual-ID architecture (PlayerID + RoomSessionID) for seamless reconnection and state preservation
  • 📱 Mobile-Optimized: HTTP-compatible UUID generation, CORS/CSRF configured for cross-origin mobile access
  • 🏗️ Modular Architecture: Clean separation of concerns with controllers, services, middleware, and routes (v4.0.0)
  • 🧪 Fully Tested: Comprehensive automated testing suite with 8 scenarios (quick to extreme load)
  • 🔒 Secure: bcrypt password hashing, session-based auth, CSRF protection, rate limiting, SQL injection prevention
  • 📊 Scalable: PostgreSQL connection pooling optimized for concurrent sessions with in-memory session tracking
  • 🐳 Easy Deploy: Single-command Docker Compose setup with automatic database initialization

Landing Page

TriviaForge Main Interface

Features

For Administrators

  • Quiz Management: Create, edit, and delete custom quizzes with an intuitive interface
  • Quiz Visibility Controls: Toggle quizzes for Live mode (presenter-led) and/or Solo mode (self-study) with visual badges
  • Question Bank: Centralized question management across all quizzes with search, filter, and archive capabilities
  • Tag System: Organize questions with customizable color-coded tags
  • Duplicate Detection: Find and manage duplicate questions with similarity-based detection and merge tools
  • Question Types: Support for Multiple Choice, True/False, and Open-Ended (Short Answer) questions
  • Open-Ended Answer Grading: Fuzzy-match auto-grading against admin-supplied accepted answers, with an admin-configurable match strictness threshold
  • Image Support: Add images to questions via file upload or external URL
  • Timer Settings: Configure per-quiz question timers and reveal delays for auto-mode
  • Results Display Toggle: Per-quiz option to show celebratory results podium with gold/silver/bronze when quiz completes
  • Drag-and-Drop Reordering: Reorganize questions and answer choices with visual drag-and-drop or arrow buttons
  • Smart Answer Tracking: Correct answer automatically updates when reordering choices
  • Excel Import: Bulk import quizzes from professionally formatted Excel templates with duplicate review (supports 2-10 answer choices)
  • Session Management: Resume interrupted sessions with full state preservation
  • Real-time Monitoring: Track active rooms and player participation live
  • User Management: View and manage all user accounts (guest, registered players, and admins)
  • Password Reset: Reset player passwords and manage account types
  • Multi-Admin Support: Multiple admin accounts with isolated quizzes and sessions
  • Admin Management (Root Admin): Create/delete admin accounts, reset admin passwords
  • Account Settings: Update email and password from any admin page
  • Session Health Monitoring: View memory usage, active sessions, and live room statistics in real-time
  • Server Settings: Configure the server URL for QR codes directly from the admin panel (no container rebuild needed)
  • PDF Export: Export richly formatted session reports as PDF — includes podium leaderboard, full player rankings, per-question accuracy chart, and detailed question breakdown with embedded images
  • Bulk PDF Export: Select multiple sessions and download a ZIP archive of individual PDF reports
  • Database Backups: Automatic daily backups (10 most recent retained) plus on-demand manual backups, with download, delete, and one-click restore. Backup files can also be re-imported into a freshly rebuilt instance (e.g. after a container/volume rebuild) so they're restorable even without the original backups volume
  • Quiz Library Export/Import: Export the full quiz library (or a single quiz) as JSON, or all questions as CSV, for sharing between instances or backing up separately from the full database

Admin Dashboard

Question Bank
Question Bank
User Management
User Management
Two-Factor Authentication
Two-Factor Authentication

For Presenters

  • Live Quiz Control: Present questions, reveal answers, and navigate through quizzes in real-time
  • Auto-Mode Timer System: Server-side timers run independently of presenter's browser with pause/resume support
  • Configurable Timers: Question timer (10-120 seconds) and reveal delay (2-30 seconds) per quiz or global defaults
  • Auto-Advance: Automatically advance to next question after reveal delay expires
  • Smart Timer Skip: All players answered detection skips remaining question timer automatically
  • Player Management: See connected players with live status indicators, organized by connection status (connected/away/disconnected)
  • Real-time Answer Progress: Track how many players have answered with percentage and animated progress bar
  • All Players Answered Notification: Visual notification when all active players have submitted answers
  • Auto-Reveal Option: Configurable 3-second auto-reveal countdown when all players answer (can be canceled)
  • Kick Player: Remove disruptive players from sessions with confirmation dialog
  • Ban Display Names: Block offensive display names globally to prevent rejoining
  • Live Standings Dashboard: Real-time leaderboard showing all players' scores, accuracy, and rankings with medal recognition for top performers
  • QR Code Generation: Quick player join via scannable QR codes
  • Session Resume: Continue interrupted quizzes exactly where you left off
  • Multi-room Support: Manage multiple concurrent trivia sessions
  • Class Performance Analytics: View overall class statistics (total correct/incorrect, class accuracy percentage, average performance)
  • Question Progress Counter: Live "X / Y" counter showing revealed questions vs total
  • Auto-Complete Detection: Quiz automatically completes when all questions have been revealed (both manual and auto-mode)

Presenter View

Live Standings

For Players

  • Mobile-Optimized Interface: Responsive design that works seamlessly on all devices (HTTP and HTTPS)
  • Solo Play Mode: Self-study mode without a presenter - browse solo-enabled quizzes and play at your own pace
  • Per-Question Timer: Countdown timer for each question with visual progress bar
  • Immediate Feedback: See correct/incorrect status immediately after answering in solo mode
  • Results Summary: Detailed breakdown of performance with per-question review after completing a quiz
  • Guest Solo Play: No account required - play solo quizzes as a guest
  • Persistent Player Identity: UUID-based PlayerID stored in localStorage for seamless reconnection across sessions
  • Wake Lock Support: Keeps mobile screens on during games (Chrome 84+, Safari 16.4+) with visual indicator
  • Enhanced Connection Stability: Infinite reconnection attempts with intelligent page visibility detection (30-second debounce)
  • Real-time Feedback: Instant answer submission and result display in live games
  • Open-Ended Answers: Type free-text answers for short-answer questions, with automatic grading; a timed-out answer auto-submits whatever's currently typed
  • Answer Locking: Prevents re-answering after submission (even on reconnection)
  • Smart Reconnection: Automatically restore progress when rejoining with full state preservation via RoomSessionID
  • Progress Tracking: Comprehensive modal showing detailed session statistics and question-by-question history with correct/incorrect/pending status (persists across disconnections)
  • Question Progress Counter: Live "X / Y" counter in navbar showing game progress
  • End-of-Game Results: Celebratory podium display showing top 3 players with gold/silver/bronze and full rankings
  • Quiz Complete Notification: Clear "Quiz Complete!" screen with countdown transition when results are enabled
  • Account System: Guest accounts with optional registration for persistent profiles
  • Recent Rooms: Quick rejoin to recently played active rooms
  • Account Management: Update display names and manage account settings
  • Session Persistence: Stay logged in for extended periods without re-authentication
  • Cross-Origin Support: Join games from any device on the local network with proper CORS/CSRF handling
  • Player Stats Dashboard: Dedicated /stats page for registered players with game history, summary stats, and trend charts
  • Performance Summary: View total games, overall accuracy, best score, multiplayer wins, average rank, and play streak
  • Trend Charts: Accuracy and score trends over time with theme-aware Chart.js visualizations
  • Game History: Paginated table of past games with quiz name, score, accuracy, rank, and type filter (solo/multiplayer)
Player Waiting
Player Lobby
Player Answering
Answering Questions
Answer Confirmation
Answer Confirmation
Desktop Player View
Desktop Player View
Countdown Timer
Countdown Timer
Player Standings
Player Standings
Theme Selection
Theme Selection
Player Overview
Mobile Interface
Solo Mode Landing
Solo Mode Landing
Solo Mode Playing
Solo Mode Playing

For Spectators

  • Display Mode: Large-screen view perfect for projectors and TVs
  • Live Results: Real-time answer distribution and statistics
  • Reveal Animations: Engaging answer reveals with visual feedback
  • Multiple Displays: Connect multiple spectator screens to the same room simultaneously
  • Question Progress Counter: Live tracking of revealed questions
  • End-of-Game Results: Full podium display on spectator screens when quiz completes

Spectator Display

Technology Stack

Backend

  • Runtime: Node.js (v20+) with ES Modules
  • Framework: Express.js (^4.18.2) with modular architecture (v4.0.0)
  • Architecture: MVC pattern with controllers, services, middleware, and routes
  • Real-time: Socket.IO (^4.7.2) with WebSocket transport and persistent session tracking
  • Database: PostgreSQL 18 with connection pooling (pg ^8.11.0)
  • Authentication: bcrypt (^6.0.0) for password hashing, session-based tokens
  • Security: CSRF protection (csrf-csrf), rate limiting (express-rate-limit), CORS (cors)
  • File Processing: ExcelJS (^4.4.0), XLSX (^0.18.5), Multer (^2.0.2)
  • Utilities: crypto (built-in), QRCode (^1.5.1), dotenv (^16.1.4), cookie-parser (^1.4.7)

Frontend

  • Framework: Vue 3 (^3.3.0) - Composition API
  • Build Tool: Vite (^8.0.8) - Fast HMR and optimized builds
  • State Management: Pinia (^2.1.0) - Vue's official state management
  • Routing: Vue Router (^4.2.0) - SPA navigation
  • HTTP Client: Axios (^1.6.0)
  • Charts: Chart.js (^4.5.1) + vue-chartjs (^5.3.3) - Theme-aware data visualization
  • Real-time Client: Socket.IO Client (^4.7.0)
  • Styling: Modern CSS3 with custom properties and responsive design
  • Theme System: 4-theme support (Light, Dark, Grey, System) with enhanced light theme visibility

Infrastructure

  • Containerization: Docker & Docker Compose
  • CI/CD: GitHub Actions — automatically builds and pushes Docker images to Docker Hub on version tag push (v*.*.*)
  • Database: PostgreSQL 18 (official Docker image)
  • Schema: Fully normalized relational design with foreign keys
  • Connection Pooling: Optimized for concurrent sessions
  • Session Persistence: Database-backed session storage

Development & Testing

  • Testing: Custom automated testing framework (HTTP-based)
  • Debug Tools: Built-in debug API and CLI tools
  • Logging: Conditional logging with connection state tracking
  • Linting: ESLint for code quality

Installation

Prerequisites

  • Docker and Docker Compose (recommended)
    • OR Node.js (v20 or higher) + PostgreSQL 18

Quick Start with Docker (Recommended)

Important: TriviaForge requires TWO containers to run:

  1. triviagame-app - The Node.js application (pulls from Docker Hub)
  2. triviagame-db - PostgreSQL 18 database (pulls from Docker Hub)

You MUST use docker-compose to start both containers together.

Choose your preferred setup method:

Option A: Command Line (Recommended)

  1. Clone the repository

    git clone git@github.com:EmanTemplar/TriviaForge.git
    cd TriviaForge
  2. ⚠️ IMPORTANT: Configure environment variables BEFORE starting

    Create your .env file from the template:

    cp .env.example .env

    Now open the .env file in a text editor and configure these REQUIRED settings:

    # REQUIRED: Set your admin password (login won't work without this!)
    ADMIN_PASSWORD=your_secure_password_here
    
    # Optional: Server URL for QR codes (can also be set in Admin > Settings tab)
    # SERVER_URL=http://192.168.1.100:3000
    
    # Optional: Set your host IP (helps with network detection)
    HOST_IP=192.168.1.100  # Replace with YOUR actual IP

    Find your IP address:

    • Windows: Run ipconfig in Command Prompt (look for IPv4 Address)
    • Mac/Linux: Run ifconfig or ip addr in Terminal

    Do not proceed until you've set ADMIN_PASSWORD in your .env file!

  3. Start the application

    docker-compose up -d

    This will:

    • Pull postgres:18 from Docker Hub
    • Pull emancodetemplar/triviaforge:latest from Docker Hub
    • Start the database and wait for it to be healthy
    • Initialize the database schema automatically (takes 30-60 seconds)
    • Start the application
  4. Verify startup

    docker-compose logs -f app

    Wait for these success messages:

    • ✅ Database connection established
    • ✅ Database initialization completed successfully
    • Server running on port 3000
  5. Access the application

    • Landing Page: http://localhost:3000 (or use your SERVER_URL)
    • Admin Panel: http://localhost:3000/index.html
    • Use the ADMIN_PASSWORD you set in your .env file

Option B: Docker Desktop UI

  1. Clone the repository

    git clone git@github.com:EmanTemplar/TriviaForge.git
    cd TriviaForge
  2. ⚠️ IMPORTANT: Configure .env file FIRST

    cp .env.example .env

    Open .env in a text editor and set at minimum:

    • ADMIN_PASSWORD=your_secure_password
    • SERVER_URL=http://YOUR_IP:3000
    • HOST_IP=YOUR_IP

    (See Option A step 2 for details)

  3. Start via Docker Desktop

    • Open Docker Desktop
    • Open a terminal in the TriviaForge directory
    • Run: docker-compose up -d
    • OR drag the project folder into Docker Desktop (if supported)
  4. Monitor in Docker Desktop UI

    • Go to Containers tab
    • You should see both containers running:
      • triviagame-app
      • triviagame-db
    • Click on triviagame-app to view logs
    • Wait for: Server running on port 3000
  5. Access the application

    • Landing Page: http://localhost:3000
    • Use the ADMIN_PASSWORD from your .env file

Common Docker Commands

View logs:

docker-compose logs -f        # All services
docker-compose logs -f app    # Just the application
docker-compose logs -f db     # Just the database

Stop the application:

docker-compose down           # Stop and remove containers
docker-compose down -v        # Also remove database volume (fresh start)

Restart after changes:

docker-compose restart        # Restart existing containers
docker-compose up -d          # Recreate containers if needed

Upgrading an Existing Install (Postgres 15 → 18)

Starting with this release, docker-compose.yml moves from postgres:15 to postgres:18. The official Postgres 18 image also changed its data volume layout, so it will refuse to start against a volume initialized by Postgres 15/16/17 — this is expected, not a bug, and no data is destroyed by the failed start.

If you have an existing deployment with real data, back up and migrate before pulling this update:

  1. On your current (pre-upgrade) install, go to Admin → Settings → Database Backups and click Create Backup. It's also worth clicking Download to keep a copy outside the container as a safety net, but it isn't strictly required — the backup file lives in the separate backups Docker volume, not pgdata, so it survives step 2 untouched.

  2. Stop the stack and remove only the old Postgres volume:

    docker-compose down
    docker volume rm <project>_pgdata   # e.g. triviagame_pgdata — check `docker volume ls`. Do NOT remove the `backups` or `uploads` volumes.
  3. Pull and start the updated stack (this initializes a fresh, empty Postgres 18 volume and lets the app run its normal schema migrations):

    docker-compose pull
    docker-compose up -d
  4. Restore your backup — go to Admin → Settings → Database Backups, find the backup from step 1 in the list, and click Restore. The app applies it and restarts automatically.

If you're running a fresh install with no existing data, skip all of this — Postgres 18 will initialize normally.

Manual Setup (Without Docker)

  1. Install PostgreSQL 18

  2. Create database

    createdb trivia
    psql trivia < app/init/tables.sql
  3. Install Node.js dependencies

    cd app
    npm install
  4. Configure environment variables

    Create .env file in app directory:

    DATABASE_URL=postgres://your_user:your_password@localhost:5432/trivia
    ADMIN_PASSWORD=your_secure_password_here
    APP_PORT=3000
  5. Start the server

    npm start

Usage Guide

Creating a Quiz

Method 1: Manual Creation (Admin Panel)

  1. Navigate to the Admin panel
  2. Enter admin password
  3. Fill in quiz title and description
  4. Add questions with 2-10 answer choices
  5. Mark the correct answer for each question
  6. Click "Save Quiz"

Method 2: Excel Import

  1. Download the Excel template from the Admin panel
  2. Fill in your quiz data following the template format:
    • Column A: Question text
    • Columns B-K: Answer choices (2-10 choices)
    • Column L: Correct answer index (0-9)
  3. Upload the completed Excel file
  4. Review and save the imported quiz

Quiz Creation Interface

Running a Live Session

  1. Presenter Setup

    • Open the Presenter page
    • Select a quiz from the dropdown
    • Click "Make Live" to create a room
    • Share the room code or QR code with players
  2. Player Join

    • Players open the Player page
    • Enter room code and their name
    • Wait for questions to be presented
  3. Presenting Questions

    • Navigate through questions using Previous/Next buttons
    • Click "Present Question to Players" to show current question
    • Players submit their answers
    • Click "Reveal Answer" to show correct answer and results
  4. Completing the Session

    • Click "Complete Quiz & Save Results" to finish
    • Session data is automatically saved

Live Session in Progress

Resuming an Interrupted Session

If a session is interrupted (server restart, connection loss, etc.):

  1. Go to Presenter or Admin page
  2. Find the session in "Resume Session" or "Incomplete Sessions" dropdown
  3. Click "Resume"
  4. A new room code is generated
  5. Players rejoin with their original names to restore their progress
  6. Continue from where you left off

Resume Session Feature

Viewing Past Sessions

All completed and interrupted sessions are saved and can be reviewed:

  1. Navigate to the Admin panel
  2. Scroll to the "Completed Sessions" section
  3. View session details including:
    • Quiz title and room code
    • Start/resume timestamps
    • Player names and scores
    • Individual question results

Past Sessions History

Testing

TriviaForge includes a comprehensive automated testing suite for validating functionality and performance.

Quick Test

# Windows
test.bat quick

# Linux/Mac
./test.sh quick

Available Test Scenarios

Quick Tests (Development)

  • quick - Fast validation (3 players) - ~10s
  • session - Default test (5 players, 3 questions) - ~25s
  • verbose - Detailed logging - ~25s

Stress Tests (Performance)

  • light - Light load (5 players) - ~25s
  • medium - Medium load (15 players) - ~45s
  • heavy - Large event simulation (25 players) - ~2min
  • extreme - Maximum capacity (50 players) - ~3min
  • stress - Standard stress (20 players) - ~1min

Running Tests

# Run default test
test.bat

# Run specific scenario
test.bat heavy

# View all options
test.bat help

Custom Test Configuration

Set environment variables for custom scenarios:

# Example: 30 players, 10 questions
docker-compose exec -e TEST_PLAYERS=30 app node testing/test-runner.js

Available Environment Variables:

  • TEST_PLAYERS - Number of simulated players (default: 5)
  • TEST_QUIZ_ID - Quiz to use (default: 1)
  • TEST_ANSWER_DELAY - Max delay between answers in ms (default: 2000)
  • TEST_QUESTION_DELAY - Delay between questions in ms (default: 5000)
  • TEST_VERBOSE - Detailed logging (default: false)

Documentation

For comprehensive testing documentation, see:

File Structure

TriviaForge/
├── app/
│   ├── src/              # Backend source (v4.0.0+ Modular Architecture)
│   │   ├── config/       # Configuration modules
│   │   │   ├── constants.js    # Application constants
│   │   │   ├── database.js     # PostgreSQL connection pool
│   │   │   ├── environment.js  # Environment variable access
│   │   │   └── version.js      # Centralized version management
│   │   ├── controllers/  # REST API controllers
│   │   │   ├── auth.controller.js
│   │   │   ├── backup.controller.js  # Database backup/restore/import API
│   │   │   ├── quiz.controller.js
│   │   │   ├── questionBank.controller.js
│   │   │   ├── session.controller.js
│   │   │   ├── solo.controller.js    # Solo play REST API
│   │   │   ├── stats.controller.js   # Player stats API
│   │   │   ├── tag.controller.js     # Tag management
│   │   │   └── user.controller.js
│   │   ├── middleware/   # Express middleware
│   │   │   ├── auth.js         # Authentication middleware
│   │   │   └── errorHandler.js # Global error handler
│   │   ├── routes/       # REST API routes
│   │   │   ├── auth.routes.js
│   │   │   ├── backup.routes.js      # Database backup/restore/import routes
│   │   │   ├── quiz.routes.js
│   │   │   ├── questionBank.routes.js
│   │   │   ├── session.routes.js
│   │   │   ├── solo.routes.js        # Solo play routes
│   │   │   ├── stats.routes.js       # Player stats routes
│   │   │   ├── tag.routes.js         # Tag routes
│   │   │   └── user.routes.js
│   │   ├── services/     # Business logic services
│   │   │   ├── autoMode.service.js   # Server-side auto-mode timer engine
│   │   │   ├── backup.service.js     # pg_dump/restore, backup import & metadata parsing
│   │   │   ├── export.service.js     # CSV export functionality
│   │   │   ├── quiz.service.js       # Quiz data access
│   │   │   ├── room.service.js       # Live room state management
│   │   │   ├── session.service.js    # Session persistence
│   │   │   └── totp.service.js       # Two-factor authentication
│   │   └── utils/        # Utility modules
│   │       ├── constants.js   # Shared constants
│   │       ├── errors.js      # Custom error classes
│   │       ├── helpers.js     # Helper functions
│   │       ├── responses.js   # API response helpers
│   │       ├── similarity.js  # Duplicate detection algorithm
│   │       └── validators.js  # Input validation
│   ├── src/              # Frontend source (Vue 3 + Vite)
│   │   ├── main.js       # Vue app entry point
│   │   ├── App.vue       # Root component
│   │   ├── router.js     # Vue Router configuration
│   │   ├── pages/        # Page components
│   │   │   ├── LoginPage.vue
│   │   │   ├── AdminPage.vue
│   │   │   ├── PresenterPage.vue
│   │   │   ├── PlayerPage.vue
│   │   │   ├── PlayerManagePage.vue
│   │   │   ├── DisplayPage.vue
│   │   │   ├── SoloPlayPage.vue      # Solo play mode
│   │   │   └── StatsPage.vue         # Player stats dashboard
│   │   ├── components/   # Reusable Vue components
│   │   │   ├── admin/    # Admin panel components (Question Bank, Tags, Duplicates)
│   │   │   ├── common/   # Shared components (Modal, Button, AppIcon, etc.)
│   │   │   ├── modals/   # Modal components
│   │   │   ├── player/   # Player page components (CountdownTimer, etc.)
│   │   │   ├── stats/    # Player stats components (Summary, Charts, History, Navbar)
│   │   │   └── presenter/ # Presenter page components
│   │   ├── stores/       # Pinia state stores
│   │   │   ├── auth.js
│   │   │   ├── ui.js
│   │   │   ├── player.js
│   │   │   ├── question.js
│   │   │   ├── quiz.js
│   │   │   └── room.js
│   │   ├── composables/  # Vue composables
│   │   │   ├── useApi.js         # Axios wrapper (w/ CSRF)
│   │   │   ├── useAuth.js        # Authentication composable
│   │   │   ├── useLocalStorage.js # LocalStorage wrapper
│   │   │   ├── useSocket.js      # Socket.IO integration (w/ PlayerID)
│   │   │   ├── useSoloGame.js    # Solo play state management
│   │   │   ├── useTheme.js       # Theme management
│   │   │   └── useWakeLock.js    # Screen wake lock
│   │   ├── assets/       # Static assets (CSS, images)
│   │   └── main.css      # Global styles
│   ├── init/             # Database initialization SQL scripts
│   │   ├── 01-tables.sql              # PostgreSQL schema
│   │   ├── 02-migrate_timestamps.sql
│   │   ├── ...                        # Additional migrations (03-08)
│   │   ├── 09-question-tags.sql       # Question Bank & tags
│   │   ├── 10-duplicate-detection.sql # Text hash for duplicates
│   │   ├── 11-ignored-duplicate-pairs.sql # Ignored pairs
│   │   ├── 12-auto-mode-solo-play.sql # Auto-mode & solo play
│   │   ├── 13-fix-solo-guest-participants.sql # Guest participant fix
│   │   ├── 14-show-results-setting.sql    # Show results toggle
│   │   ├── 15-server-url-setting.sql      # Server URL setting
│   │   ├── 16-trusted-devices.sql         # 2FA trusted device tokens
│   │   └── 17-cleanup-display-ghost-users.sql # Prevents Display connections creating ghost users
│   ├── testing/          # Automated testing suite
│   │   ├── README.md     # Testing suite overview
│   │   ├── TESTING.md    # Complete testing guide
│   │   ├── test-runner.js
│   │   └── stress-test.config.js
│   ├── server.js         # Main server application (Express + Socket.IO)
│   ├── db-init.js        # Database initialization orchestrator
│   ├── vite.config.js    # Vite build configuration
│   ├── index.html        # HTML entry point
│   ├── Dockerfile        # Docker container definition
│   └── package.json      # Dependencies
├── test.bat              # Windows test runner wrapper
├── test.sh               # Linux/Mac test runner wrapper
├── docker-compose.yml    # Docker orchestration configuration
├── .env.example          # Environment variables template
├── LICENSE               # PolyForm Noncommercial License
├── CONTRIBUTING.md       # Contribution guidelines
├── TODO.md               # Active development tasks
├── ROADMAP.md            # Completed feature history & future plans
└── README.md             # This file

Environment Variables

Configuration Methods

Environment variables can be set in multiple ways (listed by precedence, highest to lowest):

  1. Docker Desktop UI - Set directly in the container configuration (highest priority)
  2. .env file - Place in the root directory alongside docker-compose.yml
  3. Default values - Built into docker-compose.yml (lowest priority)

Available Variables

Variable Description Default Required
APP_PORT Port number for the server 3000 No
DATABASE_URL PostgreSQL connection string postgres://trivia:trivia@db:5432/trivia Yes (auto-configured in Docker)
ADMIN_PASSWORD Password to access admin panel - Yes
HOST_IP Server IP address for network access Auto-detected No
SERVER_URL Server URL for QR codes (can also be set in Admin > Settings) Auto-detected No
SESSION_TIMEOUT Session expiration time (ms) 3600000 (1 hour) No
NODE_ENV Environment mode (development or production) production No
DEBUG_MODE Enable comprehensive debug logging (server-side) false No
TZ Timezone for timestamps America/New_York No
APP_NAME Application name TriviaForge No
SOCKET_RATE_WINDOW_MS Socket.IO rate limit window (ms) 60000 (1 min) No
SOCKET_JOIN_LIMIT Max join attempts per IP per window 50 No
SOCKET_ANSWER_LIMIT Max answer submissions per IP per window 300 No

Important Notes

  • For Docker Desktop users: Variables set in the UI will override .env file values
  • For Docker Compose CLI users: Create a .env file from .env.example and configure there
  • ADMIN_PASSWORD must be set before first run for admin login to work
  • SERVER_URL can be set in your .env file OR configured in the Admin > Settings tab. The Admin UI setting takes priority over the environment variable

Features in Detail

Excel Quiz Import

  • Download a formatted Excel template with color-coded sections
  • Support for 2-10 answer choices per question
  • Automatic validation of quiz structure
  • Preserves question formatting and special characters

Session Management

  • Dual-ID Architecture (v4.0.0): PlayerID (persistent across sessions) + RoomSessionID (per-room tracking)
  • Automatic session state saving to PostgreSQL database
  • In-memory session tracking with Maps for O(1) lookups
  • Player answer history preservation with comprehensive logging
  • Reconnection support with full state restoration (answers, progress, reconnection count)
  • Timestamp tracking for created and resumed sessions (timezone-aware)
  • Status indicators (In Progress, Interrupted, Completed)
  • Session analytics with participant performance views
  • Debug logging modes: [SESSION DEBUG], [ROOM SESSION], [JOIN DEBUG], [ANSWER DEBUG]

User Management

  • Persistent Player Identity (v4.0.0): UUID-based PlayerID stored in localStorage for seamless reconnection
  • Guest accounts created automatically on first join
  • Optional registration for persistent accounts
  • Password-protected registered player accounts
  • Session tokens with configurable timeout (default 1 hour)
  • Admin password reset functionality
  • Account type management (guest/registered/admin)
  • Recent rooms tracking with active session filtering
  • Cross-origin support with CORS and CSRF protection for mobile devices

Answer Integrity

  • Server-side validation prevents answer manipulation
  • Answer locking after submission (persists across disconnects)
  • Prevents re-answering after reveal
  • Tamper-proof answer tracking

Responsive Design

  • Mobile-first interface for players
  • Desktop-optimized admin and presenter views
  • Adaptive text sizing with viewport scaling
  • Touch-friendly controls

License

This project is licensed under the PolyForm Noncommercial License 1.0.0.

Key points:

  • ✅ Free for personal use, research, and educational purposes
  • ✅ Open source and available for modification
  • ✅ Can be used by nonprofits and educational institutions
  • ❌ Cannot be used for commercial purposes or profit-making activities

See the LICENSE file for full details.

Contributing

We welcome contributions from the community! Please read our CONTRIBUTING.md guide before submitting pull requests.

Quick guidelines:

  • By contributing, you agree your contributions will be under the same noncommercial license
  • Follow the existing code style
  • Test your changes thoroughly
  • Write clear commit messages
  • Update documentation as needed

Support

Roadmap

See ROADMAP.md for the full completed-feature history and planned future work.

Credits

Built with love for educators, event organizers, and trivia enthusiasts.

AI Assistance Disclosure

This project was developed with assistance from AI tools, including:

  • Claude Code - for code generation, debugging, and feature implementation
  • Anthropic's Claude - for architecture design and problem-solving

While AI tools were instrumental in the development process, all code has been reviewed, tested, and validated for functionality and security. The project architecture, feature decisions, and final implementation remain the responsibility of the human developers.


TriviaForge - Where Knowledge Meets Fun 🎮

About

Open Source Trivia Game that can be self hosted on a local device or home lab. Built with Vue 3, Javascript, CSS , PostgresSQL, and Socket.IO

Topics

Resources

Contributing

Stars

19 stars

Watchers

2 watching

Forks

Releases

Contributors

Languages