Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Party game for Discord voice channels: tech stack, architecture, and how our team builds with Claude Code.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Hide three words in a story. Your friends try to catch them.
A party game that runs inside Discord voice channels, built by a small team working with Claude Code.
This is a public showcase, not the game's source. The game repository is private. This repo shows the real tech stack, how the architecture protects hidden information, how a small team builds with AI, and short, non-sensitive code excerpts that illustrate the approach.查看完整 README ↗This is a public showcase, not the game's source. The game repository is private. This repo shows the real tech stack, how the architecture protects hidden information, how a small team builds with AI, and short, non-sensitive code excerpts that illustrate the approach.
MASQWORD is an independent game studio: a Ukrainian team based in Austria, founded in summer 2026 by Rostyslav Ostapenko, team of five. We build social multiplayer games for Discord and the web.
| Game | Status |
|---|---|
| MASQWORD | Playable as a Discord Activity. Pre-launch: the core game is complete and playtested with friends, public launch and community-server rollout are next. We have no public player numbers to claim. |
| Bunker (working title) | In development. A social debate game: players argue over who earns a place in the bunker. For Discord, mobile and the web. |
| Untitled word game | Coming soon. A word party game designed for Discord voice chat; our biggest game yet. |
The studio site, masqword.com, was redesigned in October 2026. It opens with the game itself: a hero built from the mask and the words on the table, then a playable sample round where you read a short story and pick the three hidden words before Discord ever loads.
| Home: the mask, the words, one call to play | Try a round: catch three words in a story, then reveal |
One player gets a situation and three secret words and tells a story out loud, working the words in naturally. Everyone else listens (voice stays in Discord or with the people in the room), throws the words they suspect onto a shared table, then votes. The reveal shows who caught which word and who smuggled one past everybody. 2–8 players, solo or in teams, in English, Spanish and Russian.
| Lobby: up to eight seats, solo or teams | Storyteller: the scene and three secret words |
| Listener: sees the table, never the secret words | Reveal: storytellers judge typos and short forms, then the table is revealed |
Screenshots come from a dev fixture with fictional players (see examples/screenshot-pipeline.py), retaken from the current build on 2026-10-13.
Players can dress their seat with a headwear piece above the portrait and a frame around it. In the game these are plain CSS and SVG (keyframed transforms, masks, gradients, no canvas and no video), and the FxGovernor turns them down on weak devices and for reduced motion. The captures below come from the same dev fixture as the screenshots above (fictional players), recorded in Edge with Playwright. Each GIF frame is rendered with the page's animations paused and stepped to an exact time, so frames are clean.
The lobby with every seat dressed. Headwear: crown with a gold glint, tube halo, fire ring, dripping halo, mint halo, shadow wings, glowing horns, neon ears. Frames: glow, radiance, sparks.
Close-ups, 1.5 s each: amethyst halo (spikes orbit the ring), fire ring (a brief jolt), crown glint, dripping halo, shadow wings, glowing horns. Rendered at 3x pixel density. The amethyst halo and the horns are shown at double speed, the other four in real time.
| Seat frames, same player and team colour: none, glow, radiance, sparks, starburst, noir star | Headwear lineup: none, neon ears, glowing horns, tube halo, dripping halo, fire ring, mint halo, amethyst halo, crown, shadow wings, thorn tiara, Monkey King circlet |
An experiment, not in the game: the same kind of effects rewritten as WebGPU fragment shaders (holo frame, noir star, spiked halo, starburst), captured from a local lab page in Edge on the machine's own Intel GPU. We use it to explore how far a shader layer could go on top of the CSS/SVG that ships today.
Shader lab (experiment): holo frame, noir star, spiked halo, starburst. In-game, every one of these is CSS/SVG.
The GIF loops are re-timed slightly so they repeat without a jump: a few CSS animations run up to about 1.3x faster or slower than in the game, the slow 60-second turn of the radiance rays becomes a gentle sway, and the shader loop is a cross-fade. The still sheets hold each animation at a flattering moment, not an average one.
| Layer | Choice |
|---|---|
| Client | Vite and vanilla JavaScript + CSS, no UI framework. A DOM party controller, not a canvas game. Self-hosted WOFF2 fonts, WebP sprites, an FxGovernor that lowers effects for reduced-motion, weak devices, long frames and Discord layout and thermal signals. |
| Discord | Discord Embedded App SDK: the client runs as an Activity inside the voice channel (lifecycle, invite dialog, Rich Presence). |
| Realtime backend | Cloudflare Workers and Durable Objects via partyserver: one SQLite-backed Durable Object per room, hibernation, alarms as authoritative phase timers. PartySocket on the client. |
| Rules | A pure reducer apply(state, action, ctx) shared by the browser mock and the server, plus a per-viewer projection projectFor(state, viewerId) so secrets never reach the wrong socket. |
| Persistence | Durable Object storage (room state and action-id dedupe), Workers KV (editable content catalogue), Workers Analytics Engine (anonymous gameplay statistics: no typed words, no names, no room codes). |
| Languages | Three UI languages (device or Discord locale) and a separate room language; scene and word packs per language, with a seeded chi-square test on the word draw. |
| Checks | Vitest: 1,059 tests in 88 files, all passing on 2026-10-13. An integration harness boots the Worker locally and drives independent authenticated clients through team, improv and shared-table flows. Playwright captures screenshots at fixed viewports. |
| Tooling | Node 22, Wrangler 4, Python (Pillow, Playwright) for brand art and the studio site. |
The private repository is organised as src/state (rules, content), src/ui (screens), src/net (sockets, reliability), src/lib (i18n, Discord, effects governor) and worker/src (room server, protocol allowlist, lifecycle, site routing, telemetry).
flowchart LR
subgraph Discord["Discord client"]
A["Activity iframe<br/>Vite + vanilla JS<br/>Embedded App SDK"]
end
subgraph CF["Cloudflare"]
W["Worker<br/>routing, static assets,<br/>host split, security headers"]
G["GameServer Durable Object<br/>one per room, authoritative<br/>apply + projectFor<br/>alarms = phase timers"]
S[("DO storage<br/>state + action-id dedupe")]
K[("Workers KV<br/>content catalogue")]
AE[("Analytics Engine<br/>anonymous events")]
end
A -- "WSS intents (PartySocket)" --> W
W -- "room code" --> G
G --- S
W --- K
G --- K
G --> AE
G -. "per-viewer projection<br/>secrets already removed" .-> A
How one action is committed (from our backend spec):
sequenceDiagram
participant C as Client
participant D as Room Durable Object
participant S as DO storage
C->>D: intent (actionId, expected phase and round)
D->>D: validate, authenticate, authorize
D->>D: stale-flow check
D->>D: apply(state, action) on a clone
D->>S: one put: state + identities + seen action ids
D-->>C: ack
D-->>C: coalesced broadcast, projectFor(state, viewer) per socket
Decisions worth knowing about:
examples/reducer-and-projection.mjs.examples/action-allowlist.mjs.examples/host-split-routing.mjs.Claude Code is our main engineering tool. Of the 247 commits in the private repository (first commit 2026-07-20, counted on 2026-10-13), 167 carry a Claude Co-Authored-By trailer, from sessions on Claude Sonnet 5.5, Opus 5.5 and Fable 5.1. A Claude Code session acts as Lead: it owns intent, architecture, integration and acceptance, and works from a rules file and a short handoff note instead of chat history. Sub-agents take bounded packets (exact files, behaviour, checks) and read-only review passes. Humans decide the product, the look and anything involving publishing or money. The working agreement is in docs/ai-workflow.md.
Concrete examples from the history (commit ids refer to the private repository):
b444d5a, 477e778). A different coding agent worked read-only alongside it in two phases: first a glossary and a risk list (words with vulgar or double meanings in Spain or Latin America, false friends, literal calques), then a line-by-line review of both dictionaries against real released localisations of party games, one table row per problem with a proposed text and a source. The agreed terminology went into the dictionaries, for example one turn is one story and a round is a full circle, lanzar and never tirar. The result was checked on screenshots of the game's phases in both languages at three viewport sizes, plus a programmatic overflow report.4cc83ed); a host action that changes the storyteller was restricted to the lobby and preparation (b2cef8f); a kicked listener stopped blocking the vote and invisible or bidirectional characters were stripped from nicknames (f5e7f85). The backend spec lists the regression tests a change of this kind must carry: forged actors, words and indices, stale versions, concurrent final contributions, durable replay after a lost ack, disconnect and host fallback.beadabf), Devin SWE-2 fixed the effects governor's timers and the avatar edge cache (c8136c2, 03a49d9), and the Lead fixed the content rules itself: pack words must be one token everywhere, client, server and catalogue, and a word swap never deals a word already in the hand (097d13b). Claude Haiku 5.5 ran read-only sweeps over client and server; the Lead reproduced every finding before acting. Some were real and fixed (c7c2fca: an echoed throw now settles the input, no dead Ready button after the preparation deadline, the next solo storyteller can start their own turn), some were rejected as working by design. Everything shipped only after the unit suite and the real-multiplayer integration run passed on a clean checkout.We are model-agnostic below the Lead. The history also shows Codex (GPT-6-Astra) used for server-side waves, Devin SWE-2 for bounded UI and Worker packets, Gemini for tooling, small tests and copy, and Claude Haiku 5.5 for fast read-only sweeps, each reviewed by the Lead before merging. We measure what each tool is good at and reassign work accordingly.
Planned, not built yet: Claude inside the product. A game master that writes fresh scenes for each table in the room's language; fair judging of near-miss guesses (typo, short form, different word); moderation and translation of community content packs before they reach other tables; short post-game recaps. We would use a small fast model for judging and moderation and a larger one for scene writing.
| Path | Content | Licence |
|---|---|---|
examples/ | Five short code excerpts with explanatory headers | MIT |
docs/ai-workflow.md | How we work with AI | All rights reserved |
screenshots/ | Four game screenshots, two studio-site captures and the app icon (WebP) | All rights reserved |
media/ | Cosmetics captures: three looping GIFs and two WebP sheets | All rights reserved |
The game's source code, scene and word content, operations tooling, sign-in and session handling, anti-abuse parameters, cosmetics artwork sources, deployment configuration and analytics configuration. They are either the product itself or would help someone attack it.
Code in examples/ is MIT. Screenshots, icon, name, artwork and written content are all rights reserved. Details in LICENSE.
ac217df, d51a396); the Lead checked it against live Clef calls and corrected the cost estimate with measured token counts (fa90a44).48cdeec). A colour or size change is one command, not a redraw. Art direction stays with a human art director; Claude Code writes and iterates the scripts.robots.txt (Claude's crawlers explicitly allowed), sitemap.xml and llms.txt, and the Worker routing that serves it is unit-tested (97f6e34). Values the owner has not confirmed stay empty and are left out, never invented. Screenshot URLs carry a content hash, so a retaken screenshot is never hidden behind a stale cache (e02eadb). See examples/studio-site-generator.py.d9fdb3e). An image-comparison model can give an advisory second opinion; it never replaces looking at the pixels or human acceptance.