什么是 EmulatorJS?模拟引擎详解

EmulatorJS 是一个开源的 JavaScript 包装器,让 libretro 内核能在任何现代浏览器中运行。这里介绍它的功能、为什么重要,以及它能做什么和不能做什么。

Mira Köhler 最后审核

定义

EmulatorJS 是一个开源的 JavaScript 前端,封装了编译为 WebAssembly 的 libretro 模拟器内核。它于 2017 年首次发布,现由 GitHub 上的贡献者社区维护。它提供一个小型、稳定的 API——加载 ROM 、设置控制、保存状态、获取截图——并隐藏底层内核的复杂性。

工作原理

libretro 是一个项目,它标准化了模拟器内核(模拟主机的 CPU、内存和图形的程序)和前端(连接控制、音频和画布的 UI)之间的接口。EmulatorJS 采用现有的用 C/C++ 编写的 libretro 内核——例如用于 SNES 的 Snes9x、用于 NES 的 FCEUmm、用于 Game Boy Advance 的 mGBA——并使用 Emscripten 将它们编译为 WebAssembly。

当你加载一个游戏时,EmulatorJS 将适当的内核流式传输到 Web Worker,为其提供 ROM 字节,并暴露一个画布让内核以每秒 60 帧的速率渲染。音频通过 Web Audio 的 AudioWorklet 路由,实现低延迟播放。输入来自键盘、屏幕触摸覆盖层或 Gamepad API。

支持的系统

EmulatorJS 支持各种卡带时代和早期光盘时代的硬件:

  • 任天堂:NES、SNES、Game Boy、Game Boy Color、Game Boy Advance、Nintendo 64
  • 世嘉:Master System、Genesis/Mega Drive、Sega CD、32X、Saturn
  • NEC:PC Engine / TurboGrafx-16、PC-FX
  • 雅达利:2600、5200、7800、Lynx、Jaguar
  • 索尼:PlayStation 1
  • SNK:Neo Geo、Neo Geo Pocket / Color
  • 其他:街机(MAME)、MSX、ColecoVision、Vectrex、WonderSwan

目前不能模拟的系统

EmulatorJS 受限于浏览器中能舒适运行的系统。PlayStation 2、GameCube、Xbox、Wii 和 3DS 无法实现——它们需要 GPU 驱动程序、浏览器因安全原因限制的 JIT 编译,以及数 GB 的 RAM。随着 WebGPU 和 SharedArrayBuffer 的成熟,它们最终会实现,但截至 2026 年中期,它们仍然只能在原生环境中运行。

EmulatorJS vs RetroArch vs 自定义 WASM 端口

RetroArch 是 libretro 的桌面和移动前端——它是与 EmulatorJS 最接近的类似物,但以原生方式运行而不是在浏览器中运行。自定义 WebAssembly 端口(例如,精心调优的 Snes9x 构建)有时在原始性能上击败 EmulatorJS,因为它们精简了 libretro 抽象层,但牺牲了广泛的系统覆盖。对于任何想要支持两个或三个以上平台的基于浏览器的网站来说,EmulatorJS 是实用的默认选择。

常见问题

EmulatorJS 是唯一的浏览器模拟器吗?
不是,但它部署最广泛。存在单个内核的自定义 WebAssembly 端口(Snes9x、mGBA、FCEUmm),以及由流媒体模拟服务构建的专有引擎。
EmulatorJS 是开源的吗?
是的。它采用 MIT 许可证,源代码位于 GitHub 上。它封装的 libretro 内核各自有单独的许可证(大多数是 GPL)。
EmulatorJS 离线工作吗?
加载内核和 ROM 后,模拟器完全在你的浏览器中运行,没有网络调用。关闭并重新打开标签页将需要重新下载内核,除非托管网站使用服务工作线程来缓存它。