Chapter 1 ยท the game
Since 2 Sep 2026 the product spec is Ben's master Source of Truth (36pp, v2026-09-02) and the rules live in Engine V4 โ packages/game-core (spec, 110 tests) ported to the app as apps/sot-engine.js, driven by apps/sot/engine.js. One line: a group plays on agreed battle days; everyone races to their adjusted target โ first eligible player there takes the Daily Win; everyone who finishes after still banks the day; Daily Wins stack into a weekly season; stakes settle when the season ends. Numbers below are read straight from the code.
The 300-rep match era this supersedes is preserved at the bottom of this page and on The four versions.
On an active day every eligible player gets a personally adjusted target โ 200 by default โ and races. The first eligible player to reach their target earns the Daily Win. The battle does not end there: it rolls on until the day's clock closes, and everyone who reaches their own target afterwards still banks the day.

How it works. Each logged set is converted to effort-adjusted reps before it hits the engine:
Bank-day continuation is the core SOT correction over the old model: a finished battle is not a dead battle. Later completers preserve their streak, earn participation credit, feed team totals and keep the feed alive โ the SOT's words: "the battle does not become meaningless after somebody wins."
Worked example (from the v4 e2e): target 200. Marco (casual ร1.25) logs 48 push-ups โ 60 reps. I steal 10% of Priya's completed 100 โ +10 to me, Priya keeps 100 (pure gain). My plank hold of 11s โ 1 rep. Then 195 push-ups โ 206 โฅ 200: Daily Win, battle stays open, Priya finishes her 200 and banks the day (streak 1), Jack misses at the deadline โ failed day, streak resets.
Failed days: at the clock's close, any eligible player under target fails the day โ streak resets to zero, failed-day counter increments, the recap says so plainly. An armed Group Shield converts a failed day into a streak-preserved one (consumed at the close it saves).
createDay / logSet / targetProgressOf / effectiveTargetOf / closeDay ยท game-core ENGINE V4Fitness tiers multiply every rep toward your target: the couch player's push-up counts more than the athlete's. The objective is similar competitive effort, not equal physical output. The exact formula beyond the tier multiplier is an open SOT question (Q217โ221).

| Tier | Multiplier | 100 physical push-ups score | Target 200 needs |
|---|---|---|---|
| Couch | ร1.5 | 150 | 134 push-ups |
| Casual | ร1.25 | 125 | 160 push-ups |
| Fit | ร1.0 | 100 | 200 push-ups |
| Athlete | ร0.85 | 85 | 236 push-ups |
Exercises convert too (a working proposal โ the official table is an open SOT gap): burpee ร2.0, push-up/squat/lunge/dip ร1.0, mountain climbers/jump rope ร0.5, and timed holds at 10 seconds = 1 rep (plank, wall sit).
The measured-heart-rate blend from the earlier engine (70% %HRR / 30% declared tier) remains in game-core, waiting on straps โ see Verification.
TIER_MULTIPLIERS / tierMultiplier ยท conversion table in apps/sot/engine.js EXERCISESStreaks count consecutive banked battle days. Rest days never break them. A failed day resets the streak โ unless the Group Shield is armed.

Streak truth lives in the engine's season record (recordBattleDay โ battleStandings) โ the live UI's optimistic counts reconcile there at every close, so a mid-day crash can't corrupt a streak.
closeDay outcomes / recordBattleDay / battleStandingsSeasons default to weekly (one pass of the group's battle days; monthly optional, Major seasons future). 1 Daily Win = 1 season point. Nothing financial or material settles on an individual day โ the season ends, then the agreed stake resolves.


| Stake | Resolves as | In the build |
|---|---|---|
| ๐ฝ Dinner | Loser buys the agreed meal (spend cap) | agreement-gated at join, obligation + mark-fulfilled at season end |
| ๐ Dare | Forfeit locked before the season | declaration frozen at creation โ can't be edited mid-season |
| ๐งน Deliverable | Practical favour owed by the loser | same obligation lifecycle |
| โค๏ธ Charity pot | Everyone contributes; winner directs the pot; disclosed platform fee | full lifecycle: contribute โ pot maths โ winner chooses charity โ donation + receipt |
Charity mechanics exactly: each player's contribution agrees up-front (points are the trial currency โ the demo displays 1 point as $1); at season end the pot totals, the platform fee (5% default, always disclosed) is deducted on screen, the winner picks from the eligible list, and the donation lands with a receipt code. The winner never receives cash โ stakes without gambling. Cash wagering is explicitly deferred by the SOT (licensing/KYC/geo โ not V1).
createBattleSeason / recordBattleDay / endBattleSeason / proposeStake / agreeToStake / contributeToCharityStake / resolveSeasonStake / designateCharity / processCharityDonationFour launch cards per the SOT โ Lightning, Rep Steal, Group Shield, Time Freeze โ plus the post-launch set. Two semantics were corrected from our earlier build: Rep Steal is a pure gain (the target keeps every rep), and Group Shield protects streaks (it does not block steals).

| Card | Effect (exact, from the engine) | Guard rails |
|---|---|---|
| โก Lightning Round | Your reps count ร3 for 10 minutes | once per player per day; window expires, the once-flag never resets |
| ๐ฅท Rep Steal | You gain 10% of a rival's completed score โ they keep every rep | once per day; counts toward your target only under the day's stealCanTriggerWin flag (our answer to SOT Q237 โ the demo sets it) |
| ๐ก Group Shield | Protects the group's streaks from one day's failures | armed any time, consumed at the close it saves; Shield Bash (competitive mode) shatters it |
| โ๏ธ Time Freeze | Battle clock +30 minutes, whole group | stack limit 1 per day |
| ๐ฃ Surprise Bomb post-launch | +20 reps lands on a rival โ deliver inside 10 minutes or it fizzles | a HIT banks the victim a +20 defusal bonus; a MISS sticks nothing (target never grows) |
| ๐ชข Rescue Rope post-launch | 50-rep credit to a mate with zero reps today | once per day, inactive players only, counts toward target |
| ๐ฅ Combo Boost ยท ๐ฒ Double Down ยท ๐ค Assist Boost ยท ๐จ Shield Bash | prescribed-sequence bonus ยท personal 2ร target quest ยท +25 both-ways on a teammate's finish ยท shatter an armed shield | in the engine, off in the default group config |
The economy question, answered in code: SOT Q240โ242 are open โ how are cards acquired, how is power kept fair, do they expire? Our live answer: a season-1 founder pack, then a daily drop each battle day, a hold cap of 4 with leftovers carrying across battles (no expiry โ cards are kept, not burned by time), and the draft-from-3 + catch-up curve from the v2 engine remains the proposal for competitive fairness. The v4 app plays all of it; this wiki keeps the receipts.
activatePowerUp / grantPowerUp / inventoryOf / resolveExpiredBombs + constants LIGHTNING_MS ยท STEAL_SHARE=0.1 ยท FREEZE_MS ยท SURPRISE_BOMB_RUF/BONUS/WINDOW ยท RESCUE_ROPE_RUF=50 ยท ASSIST_BONUS_RUF=25Two clock modes: a window (battle opens at 06:00, closes 22:00, group timezone) or a sprint (N minutes from open โ demo compression). The final stretch escalates: final 3 hours warn, the final hour banners, the final 30 โ 10 minutes are the Danger Zone.



How it works. A 1-second ticker recomputes the remaining time and the urgency level (Battle live โ Final 3 hours โ Final hour โ Final 30 โ DO OR DIE); at the level-3 threshold the whole screen washes red and the copy pushes the log. A Time Freeze overlays everything with ice while it runs. At the deadline the day auto-closes exactly once: logging locks, completions/failures/shield-saves are stamped, the day folds into the season record, and the next scheduled battle opens.
Close-call detection (SOT #98) fires when the lead gap is under 5% of target with the leader past 70% โ the "anything can happen" banner.
urgency() / snapshot() clock ยท tick() ยท deadline authority in sot-engine.js effectiveDeadlineEvery way a day can land has its own moment: You Won The Day (first to target โ the dopamine hit, confetti, canvas share card), Other Player Won (bank-your-day push), Target Completed / Day Banked (streak intact), Failed Day (comeback framing, shield note if saved), and the Battle recap (order of finish, key moments).



How it works. Win detection happens inside logSet โ the engine decides, the app renders. The win moment generates a 780ร936 canvas share card (PNG download / clipboard copy). Tone awareness (cheeky / neutral / corporate-safe) swaps every line of winner and failure copy โ the same state speaks three dialects. See App Screens โ v4 for the full screen-by-screen walk including the critical states (offline, sync conflict, rest day).
recordCompletion + app.js overlay family (#171โ183)SOT Q216: the internal unit is RUF; the UI says reps, always. Handicap math happens under the hood; the player only ever sees "reps".
How it's enforced. The v4 e2e carries two gates: a page-text regex and a source-string scan that fail the run on banned vocabulary (match / kitty / poker / RUF / 300 in UI copy) and require Daily Win / banked / reps to be present. Engine identifiers (the ruf fields) are code, not copy โ they never render.
The model that built v1โv3: any reps, any order, any mix; first to the raw target closed the match; winner = highest effort-adjusted score at closure (+15 closure bonus); 4-week seasons with 3/2/1+MVP points; comeback ร1.2 for players >30% behind; Shield blocked steals; steal transferred reps away.
What the SOT kept: effort-adjusted scoring, tier multipliers (unchanged numbers), power-up cards, the charity pot, catch-up as a design principle. What it replaced: first-to-close-ends-match โ first-to-target Daily Win with bank-day continuation; 300 โ 200 adjusted; 4-week/3-2-1 seasons โ weekly 1:1; stakes per match โ stakes per season; steal/shield semantics corrected. The old rules still run the preserved v1 app (/figma-app) and the 300-era bots โ the living history is on The four versions. The full legacy page is archived at apps/wiki/archive/game_300era_20260904.html.