此 fork 由 OpenSwiftUIProject 维护,基于 VOID001/FoloToy-Passport-Simulator,增加与 OpenSwiftUI Playground 的固件联动。
上游模拟器功能演示,点击可观看视频;此 fork 默认运行下述 2048 游戏。
在浏览器中运行 FoloToy AI Passport 的 ESP32-C3 固件。项目基于 ESP-EMU v0.42.0、WebAssembly 和 QEMU,直接模拟开发板外设,普通固件无需为浏览器单独适配。
默认且唯一内置固件为口袋 2048(社区玩法 223),
与 v0.1.0-pocket-2048
发布包的完整固件一致。源码版本为 80419bbda98e030afd742cdb9d11c8a8da4a5c42,
SHA-256 为 d6009ba20a34fdf7acb773278dc5f88425fc1f35c0c341abb505a7c11e7be36c。
来源和大小记录在 catalog.json,许可声明随
固件一起分发。
打开 OpenSwiftUIProject Simulator,
无需启动本地服务。支持内置固件、选择完整 .bin 文件、画面、按键和音频。
联网玩法、Wi-Fi 桥接和社区链接导入需要下面的本地 Node 版。
从 OpenSwiftUI Playground 构建后 Send to Simulator → Open Simulator 即可运行。两个站点同源,固件通过浏览器 IndexedDB 传递而不上传;链接仅在同一浏览器配置中 10 分钟有效,最多保留三份。到期会拒绝加载, 后续发送时清理旧记录。本地 Playground 也可直接使用此线上地址:不同源时,点击 Open Simulator 后通过窗口消息传递固件,发送完成前保持 Playground 打开。 弹窗被拦截时允许后重试;重新载入 View 时回到 Playground 再次 Open。 换浏览器或分享给别人时,请下载 full.bin 后选择文件。
目前支持:
- ST7789P3 屏幕
- UP、DOWN、OK 和 POWER 按键
- 扬声器和麦克风
- ESP32-C3 Wi-Fi、TCP、UDP、DNS 和 ICMP
- CPU 寄存器、UART 和网络检查器
- 本地固件上传和 FoloToy 社区固件导入
打开页面直接进入 2048,无需访问社区下载接口。短按 OK 切换横/纵轴,UP、DOWN 沿 当前轴移动;底部显示方向。合成 2048 或无法移动时,短按 OK 重开;长按 OK 返回固件菜单。
?id=1 和 ?play=223 都使用这份内置固件;缺失或未知 id 也回到 2048。
其他社区玩法仍可在本地 Node 版通过 ?play=<id> 导入,Pages 版可选择下载的完整固件。
按键也可使用键盘操作:
| 设备按键 | 键盘 |
|---|---|
| UP | ↑ |
| DOWN | ↓ |
| OK | Enter |
| POWER | P |
声音需要先点击页面上的“声音”。麦克风需要单独授权,并且只能在
localhost 或 HTTPS 页面使用。
- Node.js 20 或更高版本
- npm
- 支持 WebAssembly、Web Worker 和 Web Audio 的现代浏览器,推荐最新版 Chrome 或 Edge
- Docker,可选,仅用于容器部署
项目没有第三方 npm 运行依赖,WASM 运行时和示例固件已经包含在仓库中。
npm run prepare:emulator
npm startprepare:emulator 会检查固件、WASM 文件和开发板 ABI。日常开发确认文件没有变化后,
也可以直接执行 npm start。
如需让局域网设备访问:
HOST=0.0.0.0 PORT=4190 npm start点击“上传固件”可选择本地 .bin 文件,或粘贴
https://ai-passport.folotoy.cn/plays/ 下的玩法详情链接。
也可以通过模拟器 URL 的 play 参数直接加载已发布的社区玩法,例如:
http://127.0.0.1:4190/?play=100
页面会自动拉取玩法 100 的社区 Full Flash 镜像,完成校验后直接运行。
本地开发命令 npm start 会启用本地文件入口。dist/ 发布包和 Docker
镜像默认关闭该入口,只允许从 FoloToy 社区加载经过服务端校验的固件。
本地固件需要满足以下条件:
- ESP32-C3 Full Flash 合并镜像
- 从地址
0x0写入 - 不超过 8 MiB
- 包含 bootloader、分区表、应用和所需资源
上传的本地固件只保存在当前页面中,刷新后会恢复默认固件。
如需显式覆盖本地固件策略,可设置:
EMULATOR_ALLOW_LOCAL_FIRMWARE_UPLOAD=1 node server.mjs # 启用
EMULATOR_ALLOW_LOCAL_FIRMWARE_UPLOAD=0 npm start # 关闭先生成并校验 dist/:
npm test
npm run build
npm run verify:release直接运行:
cd dist
HOST=0.0.0.0 PORT=4190 npm startDocker 部署:
docker build -t ai-passport-emulator .
docker run --rm -p 4190:4190 ai-passport-emulator健康检查地址为 /healthz。线上建议在反向代理层配置 HTTPS,并允许
/api/emulator-network 的 WebSocket 升级。
主要目录和文件:
public/:页面、样式和浏览器端运行代码public/wasm/:ESP-EMU WASM 和开发板外设模拟server.mjs:静态资源、社区固件接口和健康检查logging.mjs:结构化运行日志、请求 ID 和错误字段network-bridge.mjs:虚拟 Wi-Fi 网络桥test/:Node.js 单元测试tools/:构建和发布校验脚本
常用命令:
npm start # 启动开发服务
npm test # 运行测试
npm run build # 构建 dist/
npm run verify:release # 校验发布文件
npm run start:dist # 运行 dist/ 版本前端没有额外构建步骤,修改 public/ 后刷新浏览器即可。
- CW2017 电量计尚未模拟,官方 Demo 会显示
Battery [FAIL] - BLE 控制器尚未模拟,固件进入 BLE ROM 代码时会暂停并提示不支持
- 低功耗行为与真实硬件不完全一致
- 网络只支持 IPv4,不转发分片数据包
- 默认禁止访问内网、回环和保留地址
仅在可信的本地开发环境中,可允许模拟器访问内网:
EMULATOR_NETWORK_ALLOW_PRIVATE=1 npm start浏览器中的 Swift 编辑器由 OpenSwiftUIProject/ai-passport
维护,预期 Pages 入口为 https://openswiftuiproject.github.io/ai-passport/。
本仓库的 playground/ 保留早期原型;新功能和安装说明以 ai-passport 的
tools/playground/ 为准。快速 WASM 预览不需要启动 QEMU。
默认使用上面的在线版。需要本地网络桥接时,可启动带导入 API 的本地版:
git clone --branch main https://github.com/OpenSwiftUIProject/FoloToy-Passport-Simulator.git
cd FoloToy-Passport-Simulator
npm ci
npm start -- --playground-origin https://openswiftuiproject.github.io本地预览时,将 origin 替换为页面的实际协议、主机和端口,不带路径。
本地模式将 Playground 的 Simulator URL 改为 http://127.0.0.1:4190/。点击 Send to Simulator,
再点 Open Simulator,会加载同一份完整固件并从初始状态运行。导入 API 需要本版本;
旧版可通过已开启的本地文件上传入口读取下载的 full.bin。
npm start 已启用本地上传;直接启动 server.mjs 时还需
--allow-local-firmware-upload。只配置来源不会绕过禁用本地上传的部署策略。
API 接收最多 8 MiB 的完整固件并检查 SHA-256;最多保留三份镜像,内存缓存十分钟后过期。
跨源隔离保持开启,镜像不写磁盘、不上传社区。该路径不烧录真实设备。
