给特斯拉车机做了一个游戏站:4595 款游戏是怎么进浏览器的

自建服务 · 8 分钟阅读· 30 次阅读

给特斯拉车机做了一个游戏站:4595 款游戏是怎么进浏览器的

特斯拉车机本质上就是个带轮子的浏览器,第三方 App 根本装不进去。所以「网页模拟器」几乎是唯一正路——这个站就是这么来的。

先说结论

  • 站点已经跑了:4595 款游戏、4205 个版本、67 个注册会员、4.5 万次游玩记录,FC 红白机、GBA、街机、DOS 全都有,车机浏览器打开即玩,不用装任何东西
  • 技术栈土得很:PHP + MySQL + EmulatorJS,没有一行"高级"的东西
  • 真正花时间的不是写网站,是三件事:游戏从哪来、手柄为什么失灵、车机上怎么全屏

悦宝游戏首页

这站是给谁做的

车机的使用场景很特殊:等人、充电、洗车的二三十分钟,一块大屏 + 一副手柄,是现成的游戏机。但特斯拉的原生系统没有任何游戏生态能装,App Store 也没有。好在车机浏览器是全功能的,所以整个方案就是:一个对车机优化过的网页,游戏全在浏览器里跑。

功能上现在有这些:游戏库、好友、排行榜、月光宝盒、声浪模拟,微信扫码登录,会员畅玩全部游戏。其中「车机全屏」是个单独入口,点进去会顺带让浏览器进入全屏,把状态栏和地址栏都藏掉。

游戏从哪来:90% 的时间花在这

先核查,再下载

血的教训是:源站清单拉了 3230 条,逐条和站内条目匹配之后,真正能对上的 ROM 只有 221 个,归并成 158 个游戏。如果一开始就闷头把几个 GB 的整包全下下来,90% 的磁盘和带宽是白花的。

所以正确顺序是:先把「要哪几个文件」算清楚,产出三份清单(入库数据、ROM 映射表、封面清单),再动手下载。

下载路上的坑

坑 现象 解法
并发写坏 zip curl 显示 0 字节但文件里有内容 单实例串行 + unzip -l 判完整后幂等跳过
exit 137 的误会 后台任务"失败"就重跑 其实 setsid 起的进程还活着,ps 确认再动手,重跑=并发写坏文件
拿 item_size 校验 永远差 21KB、无限重下 它是整个 item 的大小(含元数据),用 unzip -l 判完整性
zip 内中文乱码 老合集的文件名是 GBK 存的 没置 UTF-8 标志的按 cp437 → gbk 转回来
封面全部 404 URL 里带 [ ] curl 默认把方括号当通配符,加 -g

最后那个最冤:封面 URL 长这样 Shisen Mahjian 2 (As) [!].jpg,18 张"失败"的封面加上 -g 之后 18/18 全部成功。

双表设计:一个游戏,N 个版本

中文汉化 ROM 的现实是:同一个游戏有 N 个汉化组的版本。所以库是两张表:

games         : id, title, platform, rom_path, cover_path, merged_into, ...
game_versions : id, game_id, version_title, rom_path, custom_core, ...

比如「口袋妖怪绿宝石」是 1 条 games + 6 条 versions,六个汉化组版本共用一个条目、六个存档位。另外「能不能玩」的判据是 game_versions 里有 rom_path 非空的行,不是 games 表那个字段——空壳条目也可能有值,拿错口径统计会得出「0 空壳」的假象。

分类体系:把玩法类型整个搬过来

站内的分类是双轴的:平台轴(GBA、红白机 FC、街机、DOS 游戏)+ 玩法轴(动作、格斗、射击、竞速、体育、冒险、角色扮演、战略、模拟、益智、养成、棋牌、其他,一共 13 类)。这套玩法类型是从源站整个搬过来重建的,比拍脑袋自己编靠谱得多,玩家按"想玩什么类型"找游戏才找得到。

手柄失灵:查得最久的一关

网页模拟器接实体手柄,症状千奇百怪。排查下来一共八个根因,挑三个最狠的:

症状 根因
键盘能玩,手柄全废 引擎的 connected 事件在构造函数里就轮询完了,宿主后注册的监听器永远收不到
插上第二个手柄,两个都废 引擎拿手柄"原始 index"当数组下标,跳号就把输入静默发给别人,越界还断链
清缓存能好一阵,过会儿又不行 键位表被 localStorage 持久化污染,永不自愈
FC 上推左摇杆没反应 引擎把"轴"和"十字键"放在互不相通的槽位上

修完还做了一件事:照引擎控件表把整份机型清单一次定死(哪些机型自带类比摇杆、哪些只转换十字键),再用测试守着,不然用户会一个机型一个机型来提"XX 也给我加上摇杆"。

车机适配的小事

  • 车机环境用 car-detect.js 识别,识别到之后切专门的 UI 模式
  • DOS 游戏的自托管内核放在 immutable 的一年缓存目录里,内核一改必须换目录名,不然车机端永远拿旧缓存,这个问题排查起来极其隐蔽
  • 声浪模拟不是放音频文件:发动机声是纯代码实时合成的,怠速、加速、减速、巡航四个工况分开调

游戏详情页:20 个版本、累计游玩 45 万次、联机对战

现在的数据

项 数值
游戏条目 4595
版本行 4205
注册会员 67
累计游玩记录 45472

热门榜前排:超级马里奥合集、西游释厄传、魂斗罗合集、合金弹头合集——怀旧游戏的口味果然和当年街机厅一模一样。

周榜:合金弹头合集、西游释厄传、恐龙新世纪

相关阅读

评论 (0)

还没有评论,来说两句吧~

发表评论

验证码

提交后需站长审核,通过后才会显示。