尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證RBMK Nuclear Reactor Simulation Game
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Manage a nuclear reactor in real time. Control the forces involved to meet power targets and avoid a nuclear disaster. Open the Simulation here
You are the reactor control engineer on Unit 4. Deliver the power output the grid asks for. Don't let the reactor fail either way: a meltdown (reactor temperature reaches 1,200°) or a core explosion (steam reaches 600). If your performance falls to 0%, you are removed from your post.
Every mode runs the same physics. Only the workload changes.
| Mode | Shift | Workload |
|---|---|---|
| Easy | 15 min | 7 events: one major emergency, smaller events and target changes |
| Hard | 30 min | 14 events: both major emergencies, tougher, plus smaller events and larger target changes |
| Free | Unlimited | Sandbox: no targets, no events |
| Safety Test | 20 min | A scripted recreation of the Unit 4 turbine rundown test (25–26 April 1986) |
The model follows Legasov's courtroom explanation. Every second, the cards in play decide whether radioactivity (the fission level) grows or shrinks, in proportion to its current level.
Radioactivity heats the fuel. The fuel heats the reactor, the reactor boils water into steam, and the steam pushes radioactivity up again. A rise left alone feeds itself into disaster. A fall feeds itself into the xenon pit. Power output is steam × 50 MW while the turbine is on the grid, so it lags behind radioactivity.
Stay within ±10% of the target (never tighter than ±200 MW) and performance climbs. Outside that band it falls. The grid warns of each target change 60 s ahead. In Easy and Hard the shift brings emergencies too: power cuts, control rod jams, pump trips, grid holds and turbine trips. Full rules are on the in-game How to Play page.
A Next.js 16 / React 19 app (Tailwind, shadcn/ui), deployed on Vercel. The key design choice: everything that decides what happens is plain, pure TypeScript with no React. The UI only shows the state and sends the player's inputs. That split is what makes the testing below possible.
┌──────────────────────────── lib/ (pure, no React) ────────────────────────────┐
player input → │ advanceGame(state, rng) ── one second of the whole game │ → new GameState
│ ├─ sim/reactor.ts reactor physics (cards, temperatures, steam, xenon) │
│ ├─ game-events.ts emergencies, power targets, turbine trip │
│ ├─ safety-test.ts the scripted Safety Test │
│ └─ game-utils.ts warnings, logging, game-over checks │
└───────────────────────────────────────────────────────────────────────────────┘
▲ every second (hooks/use-game-state.ts) ▲ thousands of times a second (scripts/sim)
the browser game the test harness and bots
lib/)lib/game-loop.ts: advanceGame is one second of the whole game as a single pure function. It runs reactor physics, the clock, events or the Safety Test script, warnings and endings. The browser and the test harness call the same function.lib/sim/reactor.ts: the reactor physics. It turns the state into a set of "reactivity cards" and steps radioactivity, fuel and reactor temperature, steam, xenon, rod travel and pump flow forward one second.lib/sim/tuning.ts: every physics number lives in one file, with comments pointing to the design section each serves. Some constants are derived, solved from a balanced reference state so the reactor stays calibrated when other numbers change. Event and power target numbers live there too (EVENT_TUNING).lib/sim/rng.ts: randomness is always passed in, never hidden. The game uses Math.random and the tests use a seeded generator, so any shift can be replayed exactly.lib/game-events.ts and lib/safety-test.ts: the shift's plan of emergencies, announced target changes and the Safety Test's timed script of orders and automated changes.lib/reactivity-board.ts, lib/sound-cues.ts, lib/rod-drive-voices.ts, lib/hum-bed.ts: pure logic behind the on-screen card board and the sound design (which cue plays when, and how voices overlap). The UI and audio layers only render them.lib/types.ts: the GameState shape, mode configs and thresholds.app/, components/, hooks/)app/: the home page with mode selection, the game (/game) and How to Play (/instructions).hooks/use-game-state.ts: ticks advanceGame once a second and saves the game to localStorage, so a refresh resumes the shift.components/: the control panel and its modals (rods, pumps, turbine), the chart recorder, the red/blue card board, the rod position display, the dosimeter, the alarm monitor, the shift log teleprinter, the reactor camera and the end screens. The incident report is styled as a paper end-of-shift report.hooks/use-audio-manager.ts: alarms, the reactor hum and sound effects, driven by the pure cue logic in lib/.ai/)ai/high-level-plan.md is the design "bible", the source of truth for what the player should experience. It is organised by area (reactivity, temperatures, pumps, turbine, xenon, rods, events, targets, Safety Test, presentation). Each section gives the change, the player outcome, what must be preserved, and acceptance checks.ai/implementation-plan.md maps the bible onto code and records each iteration. If the two disagree, the bible wins.ai/high-level-plan-changelog.md records why the design changed.The physics, events and Safety Test are tested against what the player should experience, not against implementation details. Every acceptance check in the bible is written as observable behaviour. Each one is an automated test named after its bible section:
✔ §6 hot fuel never stops a rise: with rods and pumps unchanged, a small push ends in disaster
✔ §7 losing all pumps at high radioactivity can be saved by rapid rod insertion
✔ §9 collapse to full xenon takes several minutes
✔ §13 a competent player meets the targets on Easy and Hard, and Hard is harder
✔ §14 surviving to the end is possible with skilful play; ignoring the test ends in disaster
✔ §14 a reactor collapsed when the test begins: every rod is ordered out, and only AZ-5 saves it
There are 67 checks across physics, events and targets, the Safety Test, the card board and sound cues. Because the game is pure functions with injected randomness, the whole suite plays many minutes of reactor time and runs in about a second. That changes how the game is developed:
scripts/sim/bot.ts is a scripted "competent player". It reads only what the panel shows (radioactivity and its trend, output, target, temperatures, steam, lamps) and acts every few seconds, like a person. Its play style can be varied: cadence, number of pumps, a reckless rod-pulling strategy, or how it responds when the Safety Test begins. So claims like "a competent player meets the targets on Easy" or "Hard is harder" are measured over whole simulated shifts through the real game loop, not guessed.Node 24, no extra installs: the harness uses Node's built-in test runner and TypeScript support.
| Command | What it does |
|---|---|
node --run sim:test | Runs every acceptance check |
node --run sim:trace -- <scenario> | Prints a second-by-second trace (steady, pumps0–pumps4, collapse, restart) |
node --run sim:shift [-- seed] | Plays hands-off Easy, Hard and Safety Test shifts through the real game loop and prints their logs |
npx tsc --noEmit -p . | Type check (the Next build ignores type errors, so this is the real gate) |
npm run dev | Runs the game locally |
The sound key in the header has two switches that share one volume: Alarms, which sound while a warning or emergency lasts, and Sound effects (reactor hum, control clicks, rod drives, AZ-5, warning bleeps and the shift log teleprinter). Nothing plays while the game is paused.
Sound effects and 'control room' image obtained from Pixabay