//
- Prize
- Build
- Until
- Mods
Player vs Game
At the top of every hour PvG makes a game on the spot and puts it live. Each one is named after a stock. Finish a run while it's live, enter your Solana wallet, and if you're in the hour's top 10 you get an airdrop: the top 10 split a share of the token's creator fees, paid in SOL. Older games stay open for practice.
On the air
The clock splits time into 12-hour blocks and gives every stock one hour per block. This is the block we're in.
01 · One file
Every game PvG makes is a single TypeScript file. It
exports a pitch, its controls, a create() that
builds the whole game from a seed, and a bot that can play
it.
02 · Ten checks
Each game is bundled on its own and run headless, with
Math.random, Math.sin and friends
and the clock rigged to throw.
03 · The clock
Every 12 hours the twelve stocks are shuffled into a new order, and each hour the next one gets its game. Your browser works this out from the time alone, with no server to ask.
04 · The seed
The game's id and the hour hash into one 32-bit number. That seed is this hour's build: the same for every player, different every hour.
05 · The mods
Each build draws 2–4 modifiers, so this hour never plays like the last. Some pairs can't meet, like calm air and gusty winds.
this hour:
06 · 60 steps a second
The game moves in fixed 1/60 s steps. Its randomness comes only from the seed, its trig from its own math, and it never reads the clock. Two copies fed the same inputs stay identical, frame for frame.
Two copies, one input stream.
07 · The tape
Your input is sampled once per step and written down. Repeats collapse into one entry, and pointer positions are rounded to a quarter unit so they replay exactly.
Recording the bot's run of this hour's build…
08 · Replay
Play the tape into a fresh copy and it lands on exactly the same score, so a run can be checked instead of trusted. Practice runs don't count: the top 10 live scores this hour split the fees.
The games
At the top of every hour PvG makes a new game, and it goes live the moment it's done. Everything it has made is here, newest first. Until its hour, nobody knows anything about a game, not even which stock it's for.
By the numbers
PvG-OS
| Move | ←↑↓→ or WASD |
|---|---|
| A button | Space Z J |
| B button | X K Shift |
| Start | Enter Space or tap |
| Pause | P Esc, then Q to quit |
| Retry | R Space Enter |
| Back | Esc Backspace |
| Mute | M |
Every game also plays with touch or a mouse. Its title card lists its own controls.
A run you start on the live game is a live run. When it ends you enter your Solana wallet, the run is replayed on the server, and the verified score ranks for the hour. The hour's top 10 wallets split a share of the creator fees, airdropped in SOL after the hour closes. Any other game is practice, and practice runs don't count.
Your best scores are kept in this browser for 48 hours.
Open the arcade, or go straight to a
game with /game.html?g=tsla, using its ticker in
lowercase.
Times are in your time zone; UTC is on the right. Every 12-hour block gives each stock one hour, in an order shuffled from the block number, and never the same stock twice in a row.
| Your time | Game | Prize | Build | UTC |
|---|
A build is one game at one hour. Pick a game and an hour to see its seed and mods. It's the same calculation the arcade runs.
// 32-bit FNV-1a with a murmur3 finalizer (engine/rng.ts)
function hash(str) {
let h = 0x811c9dc5;
for (let i = 0; i < str.length; i++) {
h ^= str.charCodeAt(i);
h = Math.imul(h, 0x01000193);
}
h ^= h >>> 16;
h = Math.imul(h, 0x85ebca6b);
h ^= h >>> 13;
h = Math.imul(h, 0xc2b2ae35);
h ^= h >>> 16;
return h >>> 0;
}
const hour = Math.floor(Date.now() / 3600000);
hash(`pvg:tsla:${hour}`).toString(16).toUpperCase().padStart(8, "0");
Games advance in fixed steps of 1/60 s. Gameplay
randomness comes only from the seed (mulberry32). Browsers
may disagree on the last bits of Math.sin, so
games use their own trig built from + − × ÷.
Game code never reads the clock, the DOM or the network.
A run is fully described by the game, the hour, the seed and the inputs, one per step, stored as runs of repeats.
Replaying the recorded inputs on a fresh copy of the game gives back the exact score. Drawing never feeds back into the simulation, so what you see can't change the result.
Every game goes through the ten checks in
tools/simcheck.mjs: lint, types, meta, mods,
variety, replay, idle, monkey, bot and perf.
The computer at the top of this page is a working terminal. Click its screen and type a command.
play | play this hour's live game |
|---|---|
play list | every game made so far and the next three hours |
play tsla | any game by ticker, token, company or title |
play arcade | open the arcade menu |
help | every command |
ls cd show | look around the file system |
Your move
The live game is live for another --:--.