Skip to content

Commit

Permalink
Merge pull request #2 from open-game-collective/scoring
Browse files Browse the repository at this point in the history
change scoring
  • Loading branch information
jonmumm authored Dec 15, 2024
2 parents b21723a + 500e3e5 commit 6f986e9
Show file tree
Hide file tree
Showing 22 changed files with 5,594 additions and 2,024 deletions.
1 change: 0 additions & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const config: StorybookConfig = {
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-styling",
'@storybook/addon-coverage'
],
framework: {
Expand Down
148 changes: 46 additions & 102 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,121 +1,65 @@
# Trivia Jam
# Trivia Jam 🎮

A real-time trivia game where players join from their phones and play on shared TV displays.
Trivia Jam is a real-time multiplayer trivia game designed for social gatherings, classrooms, and events. Players join from their phones while questions and scores are displayed on a shared TV or large screen.

## Game Flow
## How It Works 🎯

1. Host starts a game from their device
2. Players join using a unique game code
3. Host initiates game start
4. Host creates questions in real-time
5. Players buzz in to answer questions
6. Host validates answers
7. Points are tracked and winner is determined
1. **Host Creates Game**: A host starts a game and gets a unique game code
2. **Players Join**: Players join using the game code on their phones at triviajam.tv
3. **Questions**: The host presents numerical questions (e.g., "What year was the Declaration of Independence signed?")
4. **Fast-Paced Answers**: Players submit their answers within a time limit
5. **Scoring**: Points are awarded based on accuracy and speed:
- Exact answers get more points
- When no exact answers exist, the closest answer scores
- Faster correct answers rank higher
- Ties are handled fairly with averaged points

## Routes Structure
## Features ✨

### Main Routes
- **Real-time Gameplay**: Instant updates for all players using WebSocket technology
- **Flexible Scoring**: Supports both exact and closest-answer modes
- **Time-Based Competition**: Players race against the clock and each other
- **Multiple Display Modes**:
- Host View: Controls game flow and presents questions
- Player View: Mobile-optimized interface for submitting answers
- Spectator View: Large-screen display showing questions and scores

- `WEB_HOST/`
## Technical Stack 🛠

- Landing page
- Contains "Start New Game" button
- Redirects host to a new game session
- Built with React and TypeScript
- State management using XState and Actor Kit
- Real-time updates via WebSocket
- Storybook for component documentation
- Fully tested with interactive stories

- `WEB_HOST/games/[gameId]`
- Main game route (uses nanoid for gameId)
- Detects device type:
- Mobile: Player/Host interface
- Desktop: Game board display
## Development 🚀

### Game Board Views (Desktop)
### Prerequisites

The game board will have different views based on game state:
- Node.js 16+
- npm or yarn

1. **Lobby View**
### Setup

- Shows joining instructions
- Displays currently joined players
- Waiting for host to start
```bash
# Install dependencies
npm install

2. **Question Preparation View**
# Run development server
npm run dev

- "Waiting for next question..."
- Host is typing question
# Run Storybook
npm run storybook

3. **Active Question View**
# Run tests
npm test
```

- Displays current question
- Shows buzzer order/queue
- Displays scores
## Component Library 📚

4. **Game Over View**
- Final scores
- Winner announcement
- Option to start new game
Browse our component library and UI documentation:
[Trivia Jam Storybook](https://trivia-jam-storybook.pages.dev/)

### Player/Host Views (Mobile)
## Play Now 🎮

#### Host Views

1. **Setup View**

- Game settings
- Start game button
- Player management

2. **Question Creation View**
- Question input
- Show/hide question controls
- Answer validation interface

#### Player Views

1. **Join View**

- Name entry
- Waiting for game to start

2. **Game View**
- Buzzer button
- Current score
- Game status

## Technical Architecture

- Next.js for the frontend
- Real-time server for game state management
- JSON patch for state synchronization
- Device detection for appropriate interface rendering
- WebSocket connections for real-time updates

## Development Resources

### Storybook
The component library and UI documentation can be viewed at:
[https://trivia-jam-storybook.pages.dev/](https://trivia-jam-storybook.pages.dev/)

### Live Application
Play Trivia Jam at:
[https://triviajam.tv](https://triviajam.tv)

## State Management

The game state will be managed centrally on the server with the following key components:

- Game session data
- Connected players
- Current question
- Buzzer queue
- Player scores
- Game phase tracking

## Real-time Updates

All game state changes will be synchronized across:

- Game board display
- Host interface
- Player interfaces

Using WebSocket connections and JSON patch for efficient updates.
Try Trivia Jam at [https://triviajam.tv](https://triviajam.tv)
70 changes: 70 additions & 0 deletions app/components/help-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useStore } from "@nanostores/react";
import { atom } from "nanostores";
import { Drawer } from "vaul";

type HelpModalProps = {
$showHelp: ReturnType<typeof atom<boolean>>;
};

export function HelpModal({ $showHelp }: HelpModalProps) {
const showHelp = useStore($showHelp);

return (
<Drawer.Root open={showHelp} onOpenChange={(open) => $showHelp.set(open)}>
<Drawer.Portal>
<Drawer.Overlay className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50" />
<Drawer.Content className="bg-gradient-to-br from-indigo-900/90 to-purple-900/90 flex flex-col fixed bottom-0 left-0 right-0 max-h-[96vh] rounded-t-[10px] border-t border-white/20 z-50">
<div className="p-4 pb-6 flex-1 overflow-y-auto">
{/* Drawer handle */}
<div className="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-white/20 mb-8" />

<div className="max-w-xl mx-auto">
<h2 className="text-3xl font-bold mb-6 text-white bg-clip-text text-transparent bg-gradient-to-r from-indigo-400 to-purple-400">
How to Play
</h2>

<div className="space-y-6 text-white/90">
<div className="bg-white/10 rounded-xl p-4">
<h3 className="text-xl font-semibold mb-3 text-indigo-300">Game Basics</h3>
<ul className="space-y-2 list-disc list-inside">
<li>Answer numerical trivia questions as quickly as possible</li>
<li>All answers must be numbers (years, quantities, measurements, etc.)</li>
<li>You have 30 seconds to submit your answer for each question</li>
<li>Points are awarded based on accuracy and speed</li>
</ul>
</div>

<div className="bg-white/10 rounded-xl p-4">
<h3 className="text-xl font-semibold mb-3 text-indigo-300">Scoring</h3>
<ul className="space-y-2 list-disc list-inside">
<li>Top 30% of players can earn points each round</li>
<li>Exact answers are prioritized over close answers</li>
<li>First place: 3 points</li>
<li>Second place: 2 points</li>
<li>Third place: 1 point</li>
</ul>
</div>

<div className="bg-white/10 rounded-xl p-4">
<h3 className="text-xl font-semibold mb-3 text-indigo-300">Quick Tips</h3>
<ul className="space-y-2 list-disc list-inside">
<li>Balance speed with accuracy - both matter!</li>
<li>Watch the timer - answers lock when time runs out</li>
<li>Keep an eye on the leaderboard between questions</li>
</ul>
</div>
</div>

<button
onClick={() => $showHelp.set(false)}
className="mt-8 w-full bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-500 hover:to-purple-500 text-white font-bold py-3 px-4 rounded-xl transition duration-300 shadow-lg"
>
Let's Play!
</button>
</div>
</div>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
);
}
Loading

0 comments on commit 6f986e9

Please sign in to comment.