Skip to main content

Get Started in Minutes

This guide will walk you through setting up Showdown Trivia locally and playing your first multiplayer trivia game. You’ll create an account, configure a game room, and experience real-time competitive trivia.
1

Prerequisites

Ensure you have the following installed on your system:
# Install Go
brew install go

# Install MongoDB
brew tap mongodb/brew
brew install mongodb-community

# Start MongoDB
brew services start mongodb-community
Minimum Requirements:
  • Go 1.21 or higher
  • MongoDB 4.4 or higher
  • 512MB RAM (1GB recommended)
2

Clone and Configure

Clone the repository and set up your environment configuration:
# Clone the repository
git clone https://github.com/Lafetz/multiplayer-trivia.git
cd multiplayer-trivia

# Create environment configuration
touch .env
Configure your .env file with the following settings:
.env
# Database connection string
DB_URL=mongodb://localhost:27017/showdown-trivia

# Server port
PORT=8080

# Logging level: debug, info, warn, error
LOG_LEVEL=info

# Environment: dev or prod
ENV=dev
VariableRequiredDescriptionValid Values
DB_URLYesMongoDB connection stringAny valid MongoDB URI
PORTYesHTTP server portAny valid port number
LOG_LEVELYesApplication logging verbositydebug, info, warn, error
ENVYesRuntime environmentdev, prod
The application will fail to start if any required environment variables are missing or invalid. Configuration is validated at startup:
// Configuration validation from internal/config/config.go
func (c *Config) loadEnv() error {
    if os.Getenv("DB_URL") == "" {
        return ErrInvalidDbUrl
    }
    if os.Getenv("LOG_LEVEL") == "" {
        return ErrLogLevel
    }
    // ... additional validation
}
3

Install Dependencies and Build

Install the required Go modules and build the application:
# Download Go dependencies
go mod download

# Build the application
go build -o showdown-trivia ./cmd/web

# Run the application
./showdown-trivia
You should see output similar to:
2026/03/03 10:30:45 INFO db connected
2026/03/03 10:30:45 INFO Starting server on :8080
If you prefer using Make for development:
# Install development tools (Tailwind, Templ, Air for hot-reload)
make install-tools

# Run in development mode with hot-reload
make dev

# Build for production
make build
For a containerized setup that includes MongoDB:
# Build and start all services
docker compose up --build

# Run in detached mode
docker compose up -d

# View logs
docker compose logs -f

# Stop services
docker compose down
Docker Compose automatically configures networking between the app and MongoDB.
4

Create Your Account

Navigate to the application and create your player account:
  1. Open your browser to http://localhost:8080
  2. Click Sign Up in the navigation
  3. Fill out the registration form:
    • Username: Your display name in games (3-20 characters)
    • Email: Must be unique
    • Password: Minimum 8 characters
  4. Submit the form
Sign Up Page
The application uses secure password hashing:
// Password is hashed before storage
hashedPassword, err := hashPassword(form.Password)
u := user.NewUser(form.Username, form.Email, hashedPassword)
_, err = userService.AddUser(u)
Account validation happens in real-time. You’ll see immediate feedback if your username or email is already taken, or if password requirements aren’t met.
5

Sign In

After successful registration, sign in with your credentials:
  1. Navigate to http://localhost:8080/signin
  2. Enter your email and password
  3. Click Sign In
Upon successful authentication, you’ll be redirected to the home dashboard where you can create or join games.
Game Lobby
6

Create Your First Game

Set up a new trivia game room:
  1. From the home dashboard, click Create Game
  2. Configure your game settings:
category
integer
default:"9"
Choose from 32+ trivia categories including:
  • General Knowledge (9)
  • Science & Nature (17)
  • Sports (21)
  • History (23)
  • Geography (22)
  • And many more!
amount
integer
default:"10"
Number of questions in the game (1-50)Recommended: 10-15 questions for a 5-10 minute game
timer
integer
default:"10"
Seconds per question (2-20)Shorter timers increase difficulty and excitement
  1. Click Create Game Room
The server validates your game configuration:
// Game validation from internal/web/form/game.go
if category < 0 || category > 32 {
    f.Errors["category"] = "category can't be less 0 or greater than 32"
}
if amount < 1 || amount > 50 {
    f.Errors["amount"] = "number of questions can't be less than 1 or greater than 50"
}
if time < 2 || time > 20 {
    f.Errors["timer"] = "timer can't be less than 2 or greater than 20"
}
As the game owner, you control when the game starts. The game won’t begin until you click Start Game, allowing time for other players to join.
7

Invite Players or Join Existing Games

Option A: Invite Players to Your GameShare your game room URL with friends:
http://localhost:8080/join/{room-id}
Players can join your room directly via this link. You’ll see them appear in the player list in real-time.Option B: Join an Existing Game
  1. From the home dashboard, click Browse Active Games
  2. View all available game rooms with:
    • Game owner name
    • Current player count
    • Room ID
  3. Click Join on any available game
// Active games are fetched via WebSocket
func ActiveGames(hub *ws.Hub, logger *slog.Logger) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        rooms := hub.ListRooms()
        err := render.ActiveGames(w, r, rooms)
    }
}
You cannot join games that have already started. Only games in the lobby phase appear in the active games list.
8

Play the Game

Once all players are ready:
  1. Game Owner: Click Start Game
  2. Questions appear simultaneously for all players
  3. Select your answer before the timer runs out
  4. Watch scores update in real-time after each question
  5. See the final leaderboard when all questions are answered
Active Game
Gameplay Mechanics:
// Real-time game flow from internal/core/game/game.go
func (g *Game) AskQuestion(question entities.Question, doneCh chan struct{}) {
    timer := time.NewTimer(g.timerSpan)
    g.Message <- NewMessage(MsgQuestion, question)
    
    answers := make(map[string]string)
    for {
        select {
        case answer := <-g.AnswerCh:
            answers[answer.username] = answer.answer
        case <-timer.C:
            g.endOfQuestion(question, answers)
            // Move to next question or end game
        }
    }
}
  • Each correct answer: +1 point
  • Incorrect or missed answers: 0 points
  • Fastest correct answer: No bonus (all correct answers worth the same)
  • Final scores determine winner(s)
Multiple players can tie for first place!
9

View Results and Play Again

After the final question:
  1. The winner screen displays with final scores
  2. All players are ranked by their score
  3. Return to the home dashboard to create or join another game
Want to play the same group again? The game owner can create a new room with the same settings, and players can rejoin using the new room link.

Production Deployment

Ready to deploy for public access? Check out our Docker Deployment Guide for production deployment considerations including:
  • Securing your deployment with proper authentication
  • Setting up SSL/TLS certificates
  • Configuring production environment variables
  • Using managed database hosting
  • Network security and secrets management

Monitoring Your Instance

Showdown Trivia includes built-in Prometheus metrics for monitoring:
# Access metrics endpoint
curl http://localhost:8080/metrics
Available Metrics:
  • app_websocket_connections: Current active WebSocket connections
  • app_request_game_duration: Histogram of game creation request durations
For production deployments, integrate these metrics with Prometheus and Grafana for comprehensive monitoring dashboards.

Troubleshooting

Error: db url is invalid or connection timeoutSolutions:
  • Verify MongoDB is running: mongosh (should connect successfully)
  • Check your DB_URL in .env matches your MongoDB configuration
  • For Docker: Ensure the MongoDB container is running: docker ps
  • Test connection manually:
    mongosh "mongodb://localhost:27017/showdown-trivia"
    
Error: address already in useSolutions:
  • Change the PORT in your .env file to an available port
  • Find and stop the process using port 8080:
    # macOS/Linux
    lsof -ti:8080 | xargs kill -9
    
    # Windows
    netstat -ano | findstr :8080
    taskkill /PID <PID> /F
    
Error: Games don’t load or players can’t joinSolutions:
  • Check browser console for WebSocket errors
  • Ensure your firewall allows WebSocket connections
  • If behind a proxy, ensure WebSocket upgrade headers are forwarded
  • Verify the application is running: curl http://localhost:8080/home
Error: Game created but questions don’t appearSolutions:
  • The application fetches questions from OpenTDB API - check your internet connection
  • Verify API is accessible:
    curl "https://opentdb.com/api.php?amount=10&type=multiple"
    
  • Check logs for API errors: LOG_LEVEL=debug in .env
  • Some categories may have limited questions - try different categories

Next Steps

Browse Features

Explore all available features and capabilities

API Integration

Integrate with Showdown Trivia’s services

Contributing

Contribute to the project on GitHub

Deployment

Deploy to production environments

Build docs developers (and LLMs) love