Task Master Relay
A task-sequencing game where players arrange construction tasks in the correct order under time pressure. Covers three topics (Residential, Commercial, Renovation) across four difficulty tiers. Features change orders that mid-run reorder the sequence, a streak chain bonus system, and a unified 12-level progression with cumulative scoring.
Game Flow
Menu → Level Selection → Job Intro → Countdown → Playing → [Change Order] → Job Activated → ... → Game Over → Results
- Menu: Hero screen with game description, how-to-play instructions, and a Play button
- Level Selection: 12 levels grouped by difficulty (Easy/Medium/Hard/Expert), 3 topics per group. Shows stars, best score, best time, and cumulative total
- Job Intro: Shows job card with image, title, description, and tile count. First job triggers countdown; subsequent jobs resume the timer
- Countdown: 3-2-1-GO via shared
Countdowncomponent - Playing: Tiles are shuffled in a bank. Drag or tap tiles into sequence slots to arrange them in correct order. Timer runs continuously across all 3 jobs. A "Review Change Order" button appears after a change order for the current job has been acknowledged
- Change Order: Mid-job interruption — a change order modal appears when 50% of slots are filled. Affected tiles return to the bank and the correct order changes
- Job Activated: Brief celebration animation (checkmark + "JOB X ACTIVATED") between jobs
- Game Over: After all 3 jobs, timer stops
- Results: Score breakdown with time score, perfect bonus, chain bonus, per-job breakdown with chain multipliers, star rating, grade, accuracy, and navigation to next level
Unlock Logic
- Level 1 always unlocked
- Completing any level unlocks the next (linear progression across topics)
- Stars: 3 stars (under par, zero penalties), 2 stars (under 1.5x par), 1 star (completed)
Topics & Content
Unified Level Map
| Level | Difficulty | Topic | Title | Pool |
|---|---|---|---|---|
| 1 | Easy | Residential Construction | Apprentice Projects | 8 jobs |
| 2 | Easy | Commercial Construction | Tenant Basics | 6 jobs |
| 3 | Easy | Renovation & Remodel | Quick Upgrades | 6 jobs |
| 4 | Medium | Residential Construction | Journeyman Projects | 8 jobs |
| 5 | Medium | Commercial Construction | Fit-Out Projects | 6 jobs |
| 6 | Medium | Renovation & Remodel | Room Makeovers | 6 jobs |
| 7 | Hard | Residential Construction | Master Builder Projects | 8 jobs |
| 8 | Hard | Commercial Construction | Full Buildout | 6 jobs |
| 9 | Hard | Renovation & Remodel | Major Renovations | 6 jobs |
| 10 | Expert | Residential Construction | Expert Projects | 6 jobs |
| 11 | Expert | Commercial Construction | Expert Buildouts | 6 jobs |
| 12 | Expert | Renovation & Remodel | Expert Renovations | 6 jobs |
Each run selects 3 jobs randomly from the level's pool and shuffles their order.
Content Structure
Level (globalId, topicId, topicName, level config)
└─ Job (id, title, description, imageUrl)
├─ Tiles[] (id, title, description, tradeIcon, imageUrl)
├─ correctOrder[] (tile IDs in sequence)
└─ changeOrder? (description, affectedTileIds, newCorrectOrder)
Topics
| Topic | Slug | Color | Description |
|---|---|---|---|
| Residential Construction | residential-construction | Amber | Framing, electrical, plumbing, roofing, HVAC for houses |
| Commercial Construction | commercial-construction | Blue | Office buildouts, retail spaces, fire systems, elevators |
| Renovation & Remodel | renovation-remodel | Green | Bathroom remodels, kitchen renovations, basement finishing |
Content stays at the "junior project coordinator" level — sequencing tasks across trades, not deep technical knowledge.
Difficulty Scaling
| Setting | Easy | Medium | Hard | Expert |
|---|---|---|---|---|
| Tiles per job | 5 | 7 | 9 | 11 |
| Par time (sec) | 90 | 150 | 240 | 360 |
| Jobs per run | 3 | 3 | 3 | 3 |
| Change order coverage | ~60-70% of jobs | ~60-70% | ~60-70% | ~67% |
Scoring
Config (single source of truth)
All values are centralized in config.ts:
JOBS_PER_LEVEL = 3
PENALTY_SECONDS = 8 // seconds added to timer per wrong activation
MAX_SCORE = 10000
TIME_PENALTY_FACTOR = 10 // -10 pts per second elapsed
PENALTY_SCORE_DEDUCTION = 350 // -350 pts per wrong activation
ACCURACY_BONUS = 500 // +500 if zero penalties
CHANGE_ORDER_TRIGGER_PERCENT = 0.5
CHAIN_MULTIPLIERS = [1.0, 1.25, 1.5]
Formula
baseScore = max(0, 10000 - elapsedSeconds × 10) - penaltyCount × 350 + (penaltyCount === 0 ? 500 : 0)
chainBonus = baseScore × (chainMultiplier - 1)
finalScore = max(0, baseScore + chainBonus)
| Factor | Value |
|---|---|
| Max score | 10,000 (before chain bonus) |
| Time penalty | -10 per second elapsed |
| Wrong activation penalty | -350 per incorrect activation + 8 seconds added to timer |
| Accuracy bonus | +500 if zero penalties across all 3 jobs |
Streak Chain Bonus
Consecutive perfect jobs (zero penalties) within a run build a chain. The chain multiplier applies to the base score as a bonus.
| Chain | Multiplier | Bonus |
|---|---|---|
| 0-1 | 1.0x | None |
| 2 | 1.25x | +25% of base score |
| 3 | 1.5x | +50% of base score |
Any penalty resets the chain to 0.
Stars
| Stars | Condition |
|---|---|
| 3 | Under par time AND zero penalties |
| 2 | Under 1.5× par time |
| 1 | Completed |
Accuracy
accuracy = penaltyCount === 0 ? 100 : max(0, 100 - penaltyCount × 20)
Grade Thresholds
Both minimum score AND minimum accuracy must be met:
| Grade | Min Score | Min Accuracy |
|---|---|---|
| S+ | 8,500 | 100% |
| S | 6,500 | 100% |
| A | 4,500 | 70% |
| B | 2,500 | 40% |
| C | 1,000 | 0% |
| D | 0 | 0% |
Results Breakdown
The results screen shows:
- Time Score: Base score minus perfect bonus component
- Perfect Bonus: +500 if zero penalties (highlighted)
- Chain Bonus: Chain multiplier applied to base score (highlighted when > 0)
- Per-job breakdown: Each job with title, completion time, chain multiplier (if > 1), and penalty time added
Platform Score
Uses the cumulative score model. After each level completion, the sum of best scores across all 12 levels is posted to the platform's score table. Per-level score is preserved in metadata. Leaderboard shows total progression via MAX(score).
TNW_COMPLETE fires once — on the player's first-ever level completion.
Change Orders
Change orders simulate real-world project disruptions. When a player fills 50% of the sequence slots, the game checks if the current job has a change order defined. If so:
- Timer pauses
- A modal describes the change (e.g., "Inspector requires a separate vent for the shower")
- Affected tiles are returned to the bank
- The correct order updates to
newCorrectOrder - Timer resumes — player must re-sequence with the new constraints
After acknowledging a change order, a "Change Order" button (with a document icon) appears in the playfield, allowing the player to review the change order details at any time during that job.
Not every job has a change order (~60-70% do). Since jobs are randomly selected and shuffled, change order timing is unpredictable across runs.
Technical Architecture
Key Files
| Area | File | Purpose |
|---|---|---|
| Types | games/task-master-relay/types.ts | GamePhase, TaskTile, JobCard, ChangeOrder, JobResult, RunState, LevelConfig, TopicConfig, TopicData, GlobalLevel, LevelProgress |
| Config | games/task-master-relay/config.ts | Scoring constants, difficulty configs, chain multipliers, par times, calculateFinalScore(), calculateChainBonus(), calculateAccuracy(), calculateStars(), getChainMultiplier() |
| Store | games/task-master-relay/store.ts | Zustand store: tile placement, slot management, timer, penalties, chain tracking, change order state machine, tap selection |
| Content API | games/task-master-relay/content.ts | getGlobalLevel(), getAllGlobalLevels(), selectRandomJobs(), TOTAL_LEVELS |
| Content Index | games/task-master-relay/content/index.ts | ALL_LEVELS array, ALL_TILE_PROMPTS, ALL_JOB_PROMPTS (image generation) |
| Topics | games/task-master-relay/content/topics.ts | Topic configs (id, name, description, icon, color, tradeName) |
| Levels | games/task-master-relay/content/levels/ | 12 individual level files (level-01.ts through level-12.ts) with job definitions, tile data, change orders |
| Helpers | games/task-master-relay/content/helpers.ts | img(), shared(), jobImg() — image path helpers |
| Shared Images | games/task-master-relay/content/shared-images.ts | TILE_STYLE, JOB_STYLE, SHARED_IMAGES — image generation prompts |
| Format | games/task-master-relay/format.ts | formatElapsedTime() — time display formatting |
| Utils | games/task-master-relay/utils.ts | shuffleArray() |
| Barrel | games/task-master-relay/index.ts | Public exports for config, store selectors, content API, and types |
| Hook | games/task-master-relay/hooks/use-game-actions.ts | updateLevelProgress(), getProgress(), getCumulativeScore() — wraps shared base |
| Audio | games/task-master-relay/hooks/use-game-audio.ts | Phase-aware SFX management |
Components
| Component | Purpose |
|---|---|
playfield.tsx | Game area: header (pause, mute, timer, penalties, chain, job dots), job card, sequence board, tile bank, Reset/Activate buttons, change order review button |
sequence-board.tsx | "Critical Path" drop zone with numbered slots, drag-and-drop and tap-to-place support, shake animation on wrong tiles |
task-tile.tsx | Individual draggable/tappable tile with image (or wrench fallback), title, description, selection highlight |
results.tsx | Score breakdown using shared ResultsScreen: time score, perfect bonus, chain bonus, per-job breakdown with chain multipliers and penalty times |
job-card-intro.tsx | Job briefing card with image, title, description, tile count. "Start Run" / "Continue" and optional "Back" |
change-order-modal.tsx | Change order interruption modal with description and affected tiles. Supports review mode ("Got It" button) |
activation-indicator.tsx | Full-screen success animation (checkmark + particles + "JOB X ACTIVATED") between jobs |
level-list.tsx | 12-level grid grouped by difficulty, with topic context (icon, color, name), progress stats, cumulative score |
how-to-play.tsx | Three-step instructions: Build Critical Path, Race the Clock (+8s per penalty), Chain Bonus |
topic-button.tsx | Topic selection card (legacy, kept for routing compatibility) |
Uses shared components: LevelCard, Countdown, PauseMenu, GameError, LoadingScreen, GameShell, GameHeader.
Routing
/task-master-relay/ → Menu (hero + Play button)
/task-master-relay/levels/ → Level selection (12 levels)
/task-master-relay/play/[level]/ → Gameplay (level = 1-12)
Old topic-based routes (/[topic]/, /[topic]/play/[level]/) redirect to /task-master-relay/.
Persistence
Storage key: task-master-relay-state
Save data:
{
levelProgress: {
level_1: { bestTimeMs, stars, unlocked, completedAt, attempts, bestScore, bestAccuracy, bestChain },
level_2: { ... },
...
},
lastPlayedLevel
}
Score submitted via submitScore(cumulativeScore, metadata). Completion signaled via signalComplete() on first-ever level completion only.
Notable Mechanics
Random Job Selection
Each level has a pool of 6-8 jobs. Each run selects 3 randomly and shuffles the presentation order, so no two runs are identical even on the same level.
Penalty Mechanics
When the player activates an incorrect sequence:
- Score deduction: -350 points per wrong activation
- Time penalty: +8 seconds added directly to the elapsed timer
- Visual feedback: Wrong tiles shake (red shake animation)
- Chain reset: Streak chain resets to 0
Both the score deduction and time addition compound — the 8 seconds also reduces the time-based score component.
Change Order State Machine
Per-job tracking with changeOrderTriggered and changeOrderAcknowledged booleans. Each job independently manages its own change order state. The trigger fires when filledSlots / totalSlots >= 0.5 and the current job defines a changeOrder. After acknowledgement, a review button allows re-reading the change order during gameplay.
Tile Interaction Modes
Supports both drag-and-drop and tap-to-place:
- Drag: Drag tile from bank to slot, or between slots
- Tap: Tap tile in bank to select, then tap slot to place. Tap two slots to swap.
- Displacement: Dropping a tile on an occupied slot returns the displaced tile to the bank
Chain Indicator
During gameplay, a chain counter appears when the streak is active. Shows the current chain multiplier (e.g., "×1.25") with a flame icon near the job progress dots.
Cumulative Score Display
The level selection screen shows both per-level stats (stars, best score, best time, accuracy, best chain) and a cumulative total across all completed levels, displayed with a trophy icon in the header.