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
在真实新加坡街区(牛车水 / 莱佛士坊 / 滨海湾)里打工、开店、投资、开车开飞机的开放世界生活模拟,浏览器即开即玩。A Singapore life sim.
Translation pending
GamesTypeScript · HTMLGitHub @contactalextangLatest connection check failedOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
REA City — 浏览器里 1:1 新加坡市中心开放世界生活模拟(Three.js + 真实开放数据)
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗浏览器里跑的开放世界:以 1:1 真实比例还原新加坡市中心约 4.8 × 2.8 km 的切片——滨海湾、莱佛士坊、牛车水、丹戎巴葛、中峇鲁、红山。路网、建筑足迹与高度、红绿灯、路灯、巴士站、MRT 出口、小贩中心都来自公开数据(OpenStreetMap、LTA DataMall、URA、HDB、NEA),离线烘焙成分块数据后流式加载。
玩法是生活模拟 + 四种身份:吃饭睡觉、上班打工、开车坐地铁,昼夜更替、雷雨天气、靠左行驶、交通罚单与警察追捕。默认身份是黑帮成员(唯一能开枪的身份),也可以在建角色界面选金领、白领、蓝领。
技术栈:Three.js 0.186 · Vite 8 · TypeScript(严格模式)。没有游戏引擎与后端,存档在浏览器 localStorage。
需要 Node ≥ 22(数据脚本直接运行 .ts)。
npm install
npm run dev # http://127.0.0.1:5173
npm run build # tsc 检查 + 打包到 dist/(多页:游戏 + dev/ 下三个工具页)
npm run check # 仅 TypeScript 类型检查
npm run preview # 预览构建产物(端口 4173)
node --test scripts/test/*.test.ts # 单元测试(碰撞、分块编解码)
public/world/sg/(约 11 MB 分块世界)与 public/assets/characters/(约 4.5 MB 角色库)已随仓库提供,不跑数据流水线也能直接玩。
| 参数 | 作用 |
|---|---|
world=grid | 改用程序生成的方格城(旧原型,回归测试基线);默认 sg 真实新加坡 |
role=gang|gold|white|blue | 临时指定身份(覆盖建角色结果,便于测试) |
fresh=1 | 忽略存档开新局,并打开建角色界面 |
creator=1 | 打开建角色界面(以已保存的角色为初值) |
chars=box | 用方块人代替骨骼角色(低配 / 排错) |
shadows=0 | 关闭实时阴影 |
music=0 | 关闭背景音乐(手机设置页也可开关;步行为轻柔氛围乐,驾车切换为车载电台) |
law=relaxed / law=real | 执法松紧。默认 casual 畅玩:只有撞人、枪击行人、攻击警察、开枪打车会招来警察,闯红灯 / 超速 / 碰撞 / 抢车 / 酒驾 / 街头赛都不追究。relaxed 恢复交通罚单(闯红灯宽限/冷却、扣 6 分,小额碰撞不立即出警,警察更慢、被捕需贴住 4 s);real 接近原版严格度。只认 URL,不存进本地设置 |
signs=0 | 关闭文字街景(路名牌、招牌、站牌等) |
props=proc | 行道树改回程序化圆锥树(默认用 threejsassets 低模阔叶树,低配可用此项省约 30 万三角面) |
fx=high|low|off | 画质:high 默认(pmndrs/postprocessing 管线:AgX + N8AO + 泛光 + 调色/颗粒/暗角/色差;物理天空 + 高度雾 + 三级联阴影 CSM 约 350 m;电影化:丁达尔光束、太阳鬼影、胶片 LUT、手持晃动、开车速度 FOV 与边缘速度模糊);low 关 AO/天空/CSM/电影化、半分辨率泛光、高分屏后期封顶 1.25 倍;off 直出(仍保留 AgX 与环境光)。街景细节(P14):high/low 用程序化外墙(凹窗、室内映射夜窗、HDB 走廊/店屋五脚基/玻璃幕墙风格)、沥青/地砖/路缘着色器、Standard 道具与树叶透光,玩家周围 3×3 块加女儿墙/檐口/檐篷柱廊/屋顶设备/空调外机/楼前铺装;off 退回平涂窗格。手机设置页「画质」可切换 |
detail=0 | 关闭 P14.2 建筑几何细节件(对比开销用) |
facdetail=0 | 关闭 P14.6 近处外墙照片扫描细节(fx=high 才有;前后对比用) |
cine=0 | 关闭 high 档的电影化效果(光束/鬼影/LUT/手持/速度 FOV/速度模糊),便于对比与排查;控制台 __game.fx.cine 可单项调强度 |
lang=zh|en | 界面语言(默认跟浏览器语言;开局右上角或手机设置「语言 / Language」可切换,切换后页面重载、存档保留)。新增界面文字一律写 t('中文') 并在 src/i18n/en/ 补英文,npm run i18n:check 检查 |
timeSpeed=N | 游戏时钟倍速 |
bright=0.7–1.6 | 画面亮度倍率(默认 1,乘到曝光上;夜里嫌暗可以调高,例如 ?bright=1.2)。手机设置页的「亮度」滑杆(70–160%)是同一个设置 |
air=0 | 不加载滨海南机场(填海岛、堤道、航空插件都不出现;排查或对比开销用) |
invertPitch=1 | 飞行俯仰反转(默认 W = 推杆、机头向下) |
story=0 | 关闭漫画剧情过场(剧情图在 public/assets/story/,缺图时也会自动跳过) |
racedbg=1 | 赛车 AI 调试:每帧记录 AI 决策文字(__game.plug.race.state().ai[i].dbg) |
线上地址 https://rea.alextang.dev。配置在 wrangler.jsonc:目前没有 main,dist/ 全部作为静态资源上传,请求不经过 Worker 代码,免费且不限流量。缓存头在 public/_headers:assets/*.js|css 带 hash,长期缓存;角色、道具、LUT、world/ 文件名固定,缓存 1 天;index.html 不缓存。
npx wrangler login # 首次:浏览器登录 Cloudflare
npm run deploy:cf # 构建 + 上传;自定义域 rea.alextang.dev 由 routes.custom_domain 自动建 DNS 与证书
部署前先跑 npm run promo:build:宣传图与剧情过场图不入库(见下方「宣传素材」),只随 dist/ 上传;本地没有 public/assets/promo/、public/assets/story/ 时线上就会缺 OG 图、标题背景与剧情图(游戏会自动降级,但分享卡片会没图)。
限制(免费版):每个版本最多 20,000 个文件、单文件不超过 25 MiB,目前 dist 约 250 个文件、最大 3.7 MB。账号与云存档的后端设计(同一 Worker + D1)和各云平台费用对比见 docs/ACCOUNTS.md。
| 按键 | 作用 |
|---|---|
| W A S D / 方向键 | 步行移动 / 驾驶 |
| Shift | 奔跑 |
| Space | 跳跃(步行) / 手刹漂移(驾驶) |
| F | 上车 / 下车(可抢 NPC 车);开的士时接招手乘客 |
| E | 进入附近地点(小贩中心、商店、MRT、住家、办公楼、工地、的士站…) |
| Tab | 手机:状态、工作、地图、角色(衣柜)、设置、存档 / 读档 / 重新开始 |
| H | 鸣喇叭(驾驶时) |
| M | 当前任务提示 |
| Enter | 切换全屏 |
| 鼠标 | 转动视角(点击画面锁定指针,Esc 解锁) |
| 鼠标左键 / 左 Ctrl | 手枪射击(仅黑帮身份;锁定指针时自动过肩瞄准) |
| Esc | 关闭面板 / 解锁鼠标;建角色界面中返回 |
开飞机(Phase AIR):机库或停机位旁按 F 登机。W / S 俯仰(W 推杆机头向下,?invertPitch=1 反转),A / D 横滚(地面兼作前轮转向),Q / E 方向舵,Shift / Ctrl 加减油门,Space 刹车(任务中为拍照 / 投放),V 追尾 / 座舱视角,T 定高定向(装了航电,手动操作即断开)。地面且速度 < 3 m/s 时按 F 下机。
触屏手机(自动识别粗指针设备;桌面可用 ?touch=1 强制开启):左半屏浮动摇杆移动 / 驾驶(推到底奔跑),右半屏拖动转视角;右下角「上车/下车」「交互」「跳/手刹」「跑」「开火」(黑帮,按住时过肩瞄准)「喇叭」(驾驶时);顶部「手机」「任务」「全屏」。手机抽屉右上角 × 关闭。竞技场 FPS 暂不支持触屏。
| 身份 | 出生 / 住家 | 初始现金 | 特点 | 工作 |
|---|---|---|---|---|
| 黑帮成员(默认) | 牛车水 52 Pagoda Street | $500 | 可开枪;犯罪累积通缉星、警察追捕 | 偷车交货、收保护费、街头破坏,及三条主线任务 |
| 金领 | 滨海湾 The Sail | $20,000 | 奢侈消费线 | 赶会议、投资(定存/指数/加密,每天 07:00 结算)、上班 |
| 白领 | 中峇鲁 78 Moh Guan Terrace | $2,000 | 房租压力 | 上班打卡(09:00–18:00)、加班(18:00–22:00) |
| 蓝领 | 红山 131 Jalan Bukit Merah | $300 | 房租压力,需求消耗 ×1.3 | 租的士载客、外卖、工地搬运 |
非黑帮身份的犯罪会降级为交通执法(罚单 + 扣分),不会触发通缉。每个身份开局都有一条新手引导任务。
饥饿与精力两条需求随游戏时间下降;偏低时减速、屏幕出现暗角,精力归零会昏倒。小贩中心(海南鸡饭、叻沙、Kopi…)和商店补饥饿,回家睡觉恢复精力。
?law=relaxed / ?law=real 下:超速、闯红灯、撞车会开罚单(扣钱 + 扣分),扣满 24 分吊销驾照一天;警署可查记录。npm run econ:sim 检查(含心情倍率和每晚娱乐花费模型);赌场 RTP 用 npm run casino:sim 检查。四个场馆在小地图上是不透明大点,离得远时钉在小地图边缘指示方向;手机「赛车 / 竞技 / 赌场 / 联系人」页顶部有场馆卡(营业时间、距离、【导航】),点导航后小地图和 HUD 指向场馆门口,走到 15 m 内自动取消。门口按 E 打开面板。打烊时面板只剩少数全天按钮(如赛道日)。
| 场馆 | 位置(sg 门口坐标) | 营业 | 玩法 |
|---|---|---|---|
| 滨海湾金沙赌场 | 滨海湾 (1319, 145) | 24 小时 | 21 点、轮盘、骰宝、百家乐、老虎机 |
| 克拉码头夜店 | 克拉码头 (66, −704) | 21:00–04:00 | 门票、点酒、节奏舞蹈、VIP 卡座、搭讪 / 约会 |
| 滨海湾赛道 | 摩天轮旁维修区 (1825, −790) | 20:00–04:00(赛道日 08:00–18:00) | 街头赛、合法赛道日 |
| 丹戎巴葛射击俱乐部 | 丹戎巴葛 (27, 563) | 24 小时 | 5v5 爆破、天梯、职业联赛、1v1、死斗 |
方格城(?world=grid)也有这四个场馆。
?law=relaxed|real 下醉驾被 40 m 内看得见你的警车(包括路边设卡的警车)发现:罚款 $2,000、扣 12 分、通缉 1 星;默认畅玩档不查酒驾。舞蹈是 124 BPM 四轨节奏游戏,用 ←↓↑→ 或 A S W D 按键,判定窗口 Perfect ±60 ms / Good ±130 ms;每晚前两曲加心情,跳得好会吸引 NPC 过来搭话。VIP 卡座需要 Lv3,最低消费 $300,全额转成当晚的酒水额度。?law=relaxed|real 下非黑帮身份跑街头赛被巡警看到会得 1 星(默认畅玩档不会)。白天的合法赛道日会封路清场,没有通缉风险,奖金较低。滨海湾大奖赛需要 Lv6。报名面板可选对手水平(见下)。| 竞技场按键 | 作用 |
|---|---|
| W A S D | 移动 |
| 鼠标 | 瞄准(点击画面锁定指针) |
| 鼠标左键 | 开火;拿着手雷时松开左键投出;拿着 C4 时按住左键下包 |
| 鼠标右键 | 开镜(AWP 两档)/ 刀重击 |
| Space | 跳 |
| C | 蹲(不用 Ctrl,避免 Ctrl+W 关掉标签页) |
| Shift | 静步(没有脚步声) |
| 1 / 2 / 3 / 4 / 5 | 主武器 / 副武器 / 刀 / 手雷(再按一次换下一种雷)/ C4 |
| 滚轮 | 依次切换武器 |
| Q | 切回上一把武器 |
| R | 换弹 |
| B | 购买菜单(数字键选类别和物品) |
| E | 下包 / 拆包(按住) |
| Tab | 计分板(按住) |
| Z | 给队友下指令:自由行动 / 跟我 / 守住这里 |
| Esc | 暂停菜单(可以投降退出) |
?bright=1.2(范围 0.7–1.6),或者在手机设置页拖「亮度」滑杆。城市南边海上的虚构填海机场「滨海南机场」(跑道 09/27,长 1200 m),从 Marina Coastal Drive 南端走堤道上岛,叫车「出行」页可以直接去。航站楼、机库、塔台都是 airport 类 POI。
law=relaxed|real 下低空(< 120 m)飞越 CBD、降落在马路上会记通缉热度;默认畅玩档不管。在家睡觉会自动存档,住家面板也可手动存档;手机里有「存档 / 读档 / 重新开始」。存档、角色外观、设置分别保存在 localStorage。
脚本在 scripts/geo/,原始数据与中间产物在 data/(已 gitignore),最终产物写到 public/world/sg/。需要 GDAL(ogr2ogr)。详细说明见 scripts/geo/README.md。
| 命令 | 步骤 |
|---|---|
npm run geo:download | 00 下载原始数据到 data/geo/raw/ |
npm run geo:extract | 01 用 ogr2ogr 按切片范围提取为 GeoJSON |
npm run geo:project | 02 投影到本地米制坐标(原点 103.8465E, 1.2825N)并裁剪 |
npm run geo:all | 依次运行下面 7 步(不含 00–02) |
geo:roads | 03 车行道路网图(车道数、单行、信号灯路口、强连通裁剪;丢弃有盖/地下/停车场通道等 service 路及穿楼 service 边) |
geo:buildings | 04 建筑足迹与高度(OSM height/levels → HDB 层数 → URA GPR → 默认值)及分类;跳过悬空/屋顶/天桥/地下体,压车行道的剔除或裁剪 |
geo:landuse | 05 土地用途栅格 → 地面贴图 |
geo:props | 06 LTA 道具点位(路灯、红绿灯、巴士站、的士站、ERP、MRT 出口、有盖走廊、天桥) |
geo:pois | 07 POI(住家、办公楼、小贩中心、MRT、警署、医院、地标、商店) |
geo:roadmesh | 08 路面网格 |
geo:chunks | 09 按 256 m 分块打包 → public/world/sg/(分块、天际线、小地图、manifest) |
geo:check | 净空检查:压车行道的建筑、地铁出口、穿楼车道边(--list 列明细,--strict 不为 0 时退出码非 0) |
原始数据来源:
角色资产:npm run char:build 把 Quaternius Ultimate Modular Men / Women(放在 data/assets-eval/)打包成 public/assets/characters/characters.glb + catalog.json(46 个部件、24 段动画、14 个预设),说明见 scripts/char/README.md。
机场模型:npm run airfield:build 把 threejsassets「Airfield — Small Airport Kit」的 22 个免费 GLB(放在 data/assets-eval/threejsassets/airfield/,需登录下载)打包成 public/assets/airfield/airfield.glb(meshopt 压缩,约 1.2 MB;--inspect 打印各模型尺寸)。
外墙细节贴图:npm run facade:build 从 ambientCG(CC0)下载 4 种照片扫描材质(缓存在 data/assets-eval/ambientcg/),处理成亮度细节 + 法线拼成 public/assets/facade/detail.webp(需系统 unzip、cwebp)。只在 fx=high 加载,?facdetail=0 关闭。
宣传素材:npm run promo:build(需系统 cwebp,用 Playwright 无头 Chromium 在 canvas 上合成)。源图是用 どこでもロケハン 把真实新加坡街区渲染成的黑白漫画线稿 + 网点 PNG:public/assets/promo/src/skyline_dusk.png、skyline_night.png(滨海湾远景)、chinatown.png、raffles.png,以及剧情过场图 public/assets/story/*.png。脚本输出 public/assets/promo/ 下的 banner.webp(README 头图 1600×500)、og.png(分享卡片 1200×630)、cover.png(itch 封面 630×500)、title-bg.webp(开始 / 加载画面背景,≤ 400 KB),并把 story/*.png 转成同名 .webp(宽 1600,已是最新则跳过);源图缺失只提示并跳过。该工具条款禁止再分发原始导出文件,所以源图和合成结果都 gitignore、不入库,只随部署上传;合成时会重新写上「© OpenStreetMap contributors · © OpenMapTiles · Terrain Tiles」署名(原图右下角的署名常被裁掉)。开始画面缺 title-bg.webp 时保持原来的纯色遮罩。源图的拍摄地点、机位和重拍脚本(node scripts/story-art/shots.mjs scripts/story-art/shots.json)见 docs/STORY-ART.md。
道具模型:npm run props:build 把 threejsassets.com 免费模型(Draco GLB,放在 data/assets-eval/threejsassets/,需登录下载)解压合并成 public/assets/props/props.glb(运行时不需要 Draco 解码器)。
src/
main.ts, config.ts 入口;全局参数(车辆手感、尺寸、NPC 上限)
core/ Game(主调度、状态机、window.__game)、Camera(追尾/过肩相机)、Input、Context(共享上下文与事件总线)、Settings(URL/本地设置)
world/ WorldSource(世界数据源接口)
SgWorld、ChunkManager、ChunkFormat、BuildingMesh、PropMeshes、RoadMarkings、Landmarks、Signage、TextAtlas 真实新加坡
GridWorld、CityGenerator、GridGraph 方格城
Airfield、AirfieldMesh、AirfieldModels、RunwayShader、HeightField 滨海南机场
RoadGraph、Pathfinder、Colliders(多边形 + 空间哈希 + 射线)、PoiMarkers、Marker
physics/ ArcadeVehicle(街机车辆)、ArcadeFlight(街机固定翼)、Collision
entities/ Player、Aircraft、Vehicle(轿车/MPV/SUV/跑车/巴士)、Pedestrians、TrafficAI、PoliceAI
characters/ CharacterLibrary、CharacterInstance、CharacterSpec、presets 骨骼角色运行时
systems/ Clock、DayNight、Weather、Signals、Law、Needs、Poi、Interactions、Jobs、Quests、Save、Spawner、Weapon、Audio、Wallet、NightLights
activities/ Plugin(娱乐插件接口)+ casino / club / race / arena / aviation 五个玩法插件
data/ roles、jobs、quests、menus、venues、casino、dates、races、arena、mood 身份、工作、任务、菜单、场馆、娱乐与经济参数
ui/ Hud、Minimap、Phone、Panels、Creator(建角色界面)、Activity(娱乐小游戏的全屏宿主)
dev/ worldViewer、charsViewer、creatorViewer 开发工具页脚本
scripts/
geo/ 数据流水线 00–09 + lib/
char/ 角色资产打包
test/ node --test 单元测试
public/world/sg/ 烘焙好的世界数据
public/assets/characters/ 角色库
launcher/ macOS 桌面启动器
npm run dev 后打开:
/dev/world.html — 新加坡世界查看器。WASD 平移、Shift 加速、鼠标拖拽环绕、T 顶视图;1–4 四个住家,5 MBS,6 Raffles Place,7 鱼尾狮,8 滨海艺术中心,9 摩天轮,0 老巴刹,G 超级树,P 达士岭,M 马里安曼庙。参数 hour=、x=&z=、shadows=0、signs=0。/dev/chars.html — 角色库与预设查看器。/dev/creator.html — 建角色界面独立测试页。window.__game浏览器控制台可用,主要供自动化测试:
stats(fps / draw calls / 三角形 / NPC 数)、world(加载耗时、区块统计)、player、role、wanted、cars、peds、policeteleport(x, z)、teleportTo(poiId)、pois.list()clock.set(hour)、clock.skip(h)、weather.set('clear'|'cloudy'|'storm')、dayNightneeds.set(h, e)、interact(poiId)、panel.choose(i)、phone.show('work')、jobs.start(id) / jobs.state、quests.*、save() / load()law.crime() / law.traffic()、signals.*plug.aviation.rent() / board() / place(x, y, z, spd, hdg) / autopilot(...) / state / jobs / start(id) / autofly() / own(id) / lineUp();window.__airfield(机场网格统计)camShot([dx,dy,dz,lx,ly,lz])(相对玩家的相机位置与注视点)、gatherPeds(r)、creator.state()launcher/make-app.sh launcher/icon-mac-1024.png # 生成 ~/Desktop/REA City.app
launcher/make-app.sh launcher/icon-mac-1024.png /Applications
双击 REA City.app:源码有改动时自动构建,启动 vite preview(127.0.0.1:4173),并用 Chrome 独立窗口打开。构建日志 /tmp/rea-build.log,服务日志 /tmp/rea-preview.log。
public/assets/characters/LICENSE-quaternius.txt)。public/assets/promo/、public/assets/story/ 已 gitignore,只随线上部署)。npm run facade:build 生成 public/assets/facade/detail.webp,随仓库提交)。public/assets/props/、public/assets/airfield/ 已 gitignore)。克隆后直接运行时会自动退回程序化行道树、机场占位与程序化 Cessna,控制台只有 [props] / [airfield] / [aircraft] 降级 warning。要用真模型:到 threejsassets.com 登录下载对应免费模型放进 data/assets-eval/threejsassets/,再跑 scripts/props/build.ts 与 npm run airfield:build。