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,即可验证所有权并自行管理介绍。
一分钟完成验证Standalone front-end for the trashmarket.fun Slots and Junk Pusher games (redesign workspace).
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
sweetardio.fun — AFTER HOURS RX / COUNTER 4444
The Sweetardio site is one closed night pharmacy, played point-and-click.
Sweetardio: 4,444 on Solana, Phase 1 at 0.0420 SOL, X @Sweetardio.
There is no homepage, no navbar and no mint button until you have earned one.查看完整 README ↗The Sweetardio site is one closed night pharmacy, played point-and-click. Sweetardio: 4,444 on Solana, Phase 1 at 0.0420 SOL, X @Sweetardio.
There is no homepage, no navbar and no mint button until you have earned one.
ROOM 1 street ──door──▶ ROOM 2 counter ──RING FOR SERVICE──▶ "the window is watching."
──UNOPENED SCRIPT──▶ ROOM 3A the Rx pad
ROOM 3A IDENTIFY YOURSELF (X / Google / email) · 3 questions · notes · wallet · side effects ──SEND TO FILL──▶
ROOM 3B the catch: cup on the tray, can on the floor
TAKE THEM ──▶ PATH A empty cup, FILLED receipt, "you can go." ──mat──▶ ROOM 1
SPIT THEM OUT ──▶ PATH B REFUSED, "good." ──▶ ROOM 4 the bag (the only mint)
src/rx/copy.ts.overlay-mobile notice first (once per browser session).
ENTER ANYWAY works, and the same four rooms are completable on a phone:
every hotspot is at least 44 × 44 px, the catch shrinks the room until the
cup and the can are both on screen, and the pad's boxes open a sheet of the
same paper with thumb-sized controls (16 px inputs, so iOS doesn't zoom).?ref= is captured silently (first touch wins), stripped from the address
bar, and filed with the intake.| Path | What |
|---|---|
src/rx/Pharmacy.tsx | The rooms and the flow between them |
src/rx/rooms/ | Street, Counter (Room 2 / 3B / Path A), RxPad (3A), Papers (receipt, stamp), Bag (Room 4), PhoneGate |
src/rx/copy.ts | Every word the pharmacy says |
src/rx/scenes.ts | Hotspot / overlay rectangles, in each painting's own pixels |
src/rx/Stage.tsx, Hotspot.tsx | Paintings, and things pinned to them |
src/rx/identity.ts | Sign-in: X, Google, or email and password (Firebase Authentication, src/firebase.config.ts) |
src/rx/usePharmacySound.ts, sfx.ts | The background loop, the street voices, the bell |
src/rx/patientFile.ts | The team's copy of each intake in Firestore (rx_files/{uid}) |
src/rx/mintWindow.tsx | The LaunchMyNFT register behind PAY AT WINDOW, and the window switch |
src/rx/device.ts, carry.ts | Phones and in-app browsers; the patient's file carried into Phantom's browser |
src/rx/progress.ts | What this browser remembers (intake draft, path, minted) |
src/rx/rx.css | All styling. Palette is locked: the five colours below, black, stained paper |
public/rx/ | The locked art, byte-for-byte as delivered. Never edited |
public/rx/web/ | Web copies derived from it (python3 scripts/rx-art.py) |
Palette: #070F34 Oxford Blue · #0313A6 Zaffre · #9201CB Dark Violet ·
#F715AB Hollywood Cerise · #34EDF3 Fluorescent Cyan.
The paintings in public/rx/ are locked. The site serves derived copies from
public/rx/web/: rooms re-encoded to WebP, props trimmed, and the papers keyed
off the black they were delivered on (colour un-premultiplied, so edges and
shadows keep no black fringe). The same script writes the 1200×630
link-preview card from the street. Re-run after replacing any original:
pip install pillow numpy
python3 scripts/rx-art.py
No catch painting (counter with the cup on the tray) was supplied, so Room 3B
composites prop-cup-full onto the counter at COUNTER.cup in
src/rx/scenes.ts. Drop a room2-catch painting in and it can replace that.
The favicons and app icons are the Sweetardio Collection badge
(public/logos/sweetardio-collection-badge-512.png), not generated.
All in public/rx/audio/:
street-bed.mp3 loops underneath the whole visit, gapless (Web Audio): full
volume on the street, half inside the pharmacy, gliding between the two as
you walk in and out. Cut from the supplied screen recording: the steady section
from 39.64 s to 86.93 s, with its last 2 s cross-faded into its first 2 s
so the loop point is seamless:
ffmpeg -ss 39.65 -t 47.3 -i recording.mp4 -vn -filter_complex "[0:a]asplit=3[a][b][c];\
[a]atrim=start=2:end=45.27,asetpts=PTS-STARTPTS[body];\
[b]atrim=start=45.27:end=47.27,asetpts=PTS-STARTPTS,afade=t=out:d=2:curve=qsin[tail];\
[c]atrim=end=2,asetpts=PTS-STARTPTS,afade=t=in:d=2:curve=qsin[head];\
[tail][head]amix=inputs=2:duration=shortest:normalize=0[xf];[body][xf]concat=n=2:v=0:a=1[out]" \
-map "[out]" -c:a libmp3lame -b:a 128k -map_metadata -1 street-bed.mp3
On the street only, street-rain.mp3 loops over it (gapless, fades out as
you go inside), with rain drawn over the painting and behind the phone
notice (src/rx/Rain.tsx; lighter and slower for reduced motion). Cut from the supplied rain recording (15.8 s) the same
way, its last 2 s cross-faded into its first 2 s:
ffmpeg -i rain-soundbible.mp3 -vn -filter_complex "[0:a]asplit=3[a][b][c];\
[a]atrim=start=2:end=13.82,asetpts=PTS-STARTPTS[body];\
[b]atrim=start=13.82:end=15.82,asetpts=PTS-STARTPTS,afade=t=out:d=2:curve=qsin[tail];\
[c]atrim=end=2,asetpts=PTS-STARTPTS,afade=t=in:d=2:curve=qsin[head];\
[tail][head]amix=inputs=2:duration=shortest:normalize=0[xf];[body][xf]concat=n=2:v=0:a=1[out]" \
-map "[out]" -c:a libmp3lame -b:a 128k -map_metadata -1 street-rain.mp3
On the street only, seven voice clips play over it one at a time, shuffled,
6–15 s apart (src/rx/usePharmacySound.ts lists them).
bell.mp3 is RING FOR SERVICE at the counter.
Browsers block sound until a visitor has touched the page, so on a first visit the street is silent until the first tap, click or key press. (iOS also ignores volume, so on iPhones the voices play at full level.)
The bag's printed PHASE 1 / 0.0420 SOL / PAY AT WINDOW sticker is the button.
Behind it is the same LaunchMyNFT Solana embed the old site used
(collection 8azF6Zkfb5ExKPty13RO, owner Hn1i…nELo). LaunchMyNFT stays
authoritative for price, eligibility, supply and the transaction; its UI is
never shown except its wallet chooser. One press connects the wallet and then
asks it to approve the mint transaction. After the embed reports success, the
patient's file is marked minted locally and, when signed in, in Firestore.
Mint locked. Whoever can't pay gets FILLED (took the meds), FILE CLOSED (already minted) or THE WINDOW IS SHUT. SIT DOWN. / DO NOT CALL THE PHARMACY. with the WINDOW CLOSED sticker — never a wallet or contract error, and never any mint UI before the trash. The window is shut when:
game_config → add a
document rx with a boolean field windowShut = true (set it to false
or delete the document to reopen; no deploy needed);sweetardio.fun.Phones. On a phone without an injected wallet, PAY AT WINDOW opens
sweetardio.fun in Phantom's own browser (its universal link), with the
patient's file carried in the address (#file=…, see
src/rx/carry.ts; minted never travels). There they tap ENTER ANYWAY,
walk in and ring, and the window sends them straight to the bag, where
Phantom is connected and pays. In X's (and other) in-app browsers, the pad
and the bag say THE WINDOW DOES NOT LIKE IN-APP BROWSERS. OPEN IN PHANTOM OR
SAFARI.
The embed script is ~8 MB, so it starts loading (hidden) at the catch, or as soon as a patient who already spat walks in. Phones without a wallet never load it.
IDENTIFY YOURSELF offers X, Google, and email/password, all Firebase
Authentication on the sweetardio project (src/rx/identity.ts). Nobody can
SEND TO FILL, and so nobody can reach the bag, without signing in. All three
are enabled in the Firebase console (Authentication):
https://sweetardio.firebaseapp.com/__/auth/handler, website
https://sweetardio.fun.sweetardio.fun is listed.Email/Password and Google can also be managed from the Firebase CLI with an
auth block in firebase.json and npx -y firebase-tools@latest deploy --only auth
(Twitter is console-only).
firestore.rules gains rx_files/{uid}: written only by the signed-in
patient themself, private to them, shape-checked, and a spat file never goes
back to took. The rules deploy on push to main via
.github/workflows/firestore-rules.yml (or npm run deploy:rules), which
needs a FIREBASE_SERVICE_ACCOUNT repo secret (a service-account key from
Firebase → Project settings → Service accounts). Until the rules are deployed,
files are not saved; the pharmacy works the same either way.
Browse them in Firestore → Data → rx_files. Each file holds how the patient
signed in, their email or X id and handle, the three answers, the note, the
wallet, the ref, the path, and minted (the patient's own claim — check the
chain before rewarding anyone).
npm install
npm run dev # http://localhost:3000
npm run build
In npm run dev the window is open on localhost. To walk the flow without
signing in, set a stand-in patient in the browser console (dev builds only):
localStorage.setItem('rx:dev-patient', JSON.stringify({ handle: 'late_night_patient' }))
Reset the file with localStorage.clear().
The arcade games (Slots, Coinpusher) are no longer part of the site, but their
wallet-free Radbro builds still ship at sweetardio.fun/radbro/slots/ and
/radbro/coinpusher/. Their source stays under src/components/slots,
src/components/junk-pusher and src/lib. See RADBRO.md.
The arcade site this pharmacy replaced is rebuilt on every deploy from its last
commit (4bcc24d) and served at sweetardio.fun/original/, marked noindex.
Typing 6969 on the vending keypad opens it. npm run build:original (after
npm run build) adds it to dist/original/; see scripts/build-original.mjs.
Changes to the old site live in scripts/original-site.patch, applied on each
build (currently: it announces "Mint is live!" and its banner links to the
mint page).
It loads its images, audio and fonts from the root, where the current
public/ still ships them unchanged, so don't remove those files while
/original/ is live.
GitHub Pages, from main, via .github/workflows/deploy.yml (public/CNAME
is sweetardio.fun).