This or That
A swipe-based card game where players identify the right tools for construction trade jobs. Swipe right to keep correct tools, left to dump incorrect ones. Covers multiple trade topics with progressive difficulty -- from basic tool identification through scenario-based decisions to system/diagram evaluation.
Game Flow
Topic Selection → Level Selection → Job Intro → Countdown → Playing (10 cards) → Results
- Topic Selection: Choose from Construction Career, Commercial Electrician, or HVAC & Plumbing
- Level Selection: 10 levels per topic with stars, high scores, and unlock progression
- Job Intro: Shows job title, description, tool count, time limit, and swipe instructions
- Countdown: 3-2-1-GO via shared
Countdowncomponent - Playing: Swipe through 10 tool cards, each showing image + name + description. Drag right (KEEP) or left (DUMP) with color overlays and rotation feedback.
- Results: Score breakdown, grade, performance review, replay/next/exit
Unlock Logic
- Level 1 always unlocked
- Next level unlocks on 60%+ accuracy
- Stars: 1 star (60%), 2 stars (75%), 3 stars (90%)
Topics & Content
| Topic | Slug | Levels | Trade Focus |
|---|---|---|---|
| Construction Career | default | 10 | Carpenter, drywall, painter, mason, plumber, electrician, HVAC, welder, heavy equipment, superintendent |
| Commercial Electrician | electrical | 10 | Electrical tools, scenarios, circuit evaluation |
| HVAC & Plumbing | hvac-plumbing | 10 | HVAC/plumbing tools, scenarios, system diagrams |
Level Progression
| Levels | Type | Description |
|---|---|---|
| 1-3 | Tool Identification | "Is this tool used by [trade]?" |
| 4-6 | Scenario-Based | "Is this the right tool for the job?" |
| 7-10 | System/Diagram Evaluation | "Is this circuit/system designed correctly?" |
Content Structure
Each level has a JobScenario with:
- Job title, description, and intro text
- Difficulty setting
- Pool of 10+ tools, each with
isCorrect, description, image URL, and explanation
Tools are shuffled before each game. Image types vary by level tier: toolPhoto, scenarioPhoto, or systemDiagram.
Time Limits
| Difficulty | Time |
|---|---|
| Easy | 45s |
| Medium | 60s |
| Hard | 120s |
| Expert | 300s |
Scoring
Final Score = Σ (Base + Speed Bonus) × Streak Multiplier + Perfect Bonus + Time Bonus
Per-Card Scoring
| Action | Points |
|---|---|
| Correct swipe | +100 |
| Wrong swipe | -50 (floor at 0) |
Speed Bonus (per card)
Up to +50 bonus points for fast decisions (under 5 seconds):
Speed Bonus = 50 × (1 - reactionTimeMs / 5000)
Streak Multiplier
Applied to base + speed bonus per card. Resets on incorrect swipe.
| Correct Streak | Multiplier |
|---|---|
| 0-2 | 1.0x |
| 3-4 | 1.25x |
| 5-6 | 1.5x |
| 7-8 | 1.75x |
| 9+ | 2.0x |
End-of-Run Bonuses
| Bonus | Value | Condition |
|---|---|---|
| Perfect Bonus | +500 | All 10 tools correct |
| Time Bonus | +5/sec remaining | Always |
Grades
| Grade | Min Score | Min Accuracy |
|---|---|---|
| S+ | 2000 | 100% |
| S | 1500 | 90% |
| A | 1000 | 80% |
| B | 600 | 70% |
| C | 300 | 60% |
Technical Architecture
Key Files
| Area | File | Purpose |
|---|---|---|
| Types | games/this-or-that/types.ts | GameStatus, LevelConfig, Tool, JobScenario, ScoreBreakdown, SwipeResult |
| Config | games/this-or-that/config.ts | Scoring constants, streak thresholds, time limits by difficulty |
| Engine | games/this-or-that/store.ts | Zustand store: phases, swipe logic, timer, streak tracking, score calculation |
| Content | games/this-or-that/content.ts | loadTopic(), getLevel(), getJob(), getAllTopics() |
| Hook | games/this-or-that/hooks/use-game-actions.ts | updateLevelProgress(), getTopicProgress() -- wraps shared base |
| Topics | games/this-or-that/content/topics/ | Per-topic configs, levels, and job definitions |
Components
| Component | Purpose |
|---|---|
card.tsx | Swipeable card with drag gestures, KEEP/DUMP overlays, rotation feedback |
playfield.tsx | Game area: score, timer, streak bar, card stack, swipe buttons, controls |
results.tsx | Score breakdown, performance review, grade, badges, action buttons |
job-intro.tsx | Level briefing with job description, stats, how-to-play tips |
level-list.tsx | Level grid with progress (stars, high score), unlock status, total earnings |
topic-button.tsx | Topic selection card with gradient styling |
how-to-play.tsx | Swipe instructions for the menu screen |
Uses shared components: LevelCard, LevelIntro, Countdown, PauseMenu, ResultsScreen, GameShell, GameHeader.
Persistence
Storage key: this-or-that-state
Save data:
{
levelProgress: { [topicId_levelId]: { highScore, stars, unlocked, completedAt, attempts } },
lastPlayedLevel, lastPlayedTopic
}
Score submitted via submitScore() with metadata: levelId, accuracy, correctCount, totalQuestions, difficulty. Completion signaled via signalComplete().
Notable Mechanics
- Swipe physics: Drag threshold, rotation proportional to drag distance, spring-back on release below threshold
- Card stack: Current card over next card with depth/scale effect
- Streak indicator: Visual bar + multiplier badge + flame icon at high streaks
- Image preloading: All tool images preloaded before level starts
- Timer urgency: Progress bar turns red under 10 seconds
- Progressive content: Moves from simple tool ID to real-world scenario evaluation to full system/diagram analysis