<!-- title: 《jsnes》他把整台红白机，塞进了浏览器 -->
<!-- domain: games -->
<!-- repo: bfirsh/jsnes -->

## 仓库档案

- **仓库**：[bfirsh/jsnes](https://github.com/bfirsh/jsnes)
- **作者**：Ben Firshner（GitHub 句柄 bfirsh），个人开发者，一个账号一个项目，没有公司背景
- **语言**：纯 JavaScript，零依赖、零编译，clone 下来就能跑
- **License**：开源授权，具体条款以仓库页面为准
- **Star**：数千星量级（据仓库页面），属于那种被无数人偷偷用了很多年的基础件
- **配套仓库**：[bfirsh/jsnes-web](https://github.com/bfirsh/jsnes-web)，官方给的 React 前端壳子，接上内核就是一个能玩的网页
- **最近更新**：老仓库，近年基本不折腾（以仓库页面为准），但模拟器这种东西，跑得稳就不需要更新

它不是一款游戏。它是一颗能跑一千款游戏的心脏——一个用 JavaScript 从零写成的红白机（FC/NES）模拟器，CPU、显卡、声卡，全在一门语言里复刻，跑在每一个浏览器里。

## 这游戏是什么

一句话：打开网页，按下键盘的方向键，你 1992 年夏天在小霸王上玩到的那个游戏，原地复活。

红白机是 1983 年任天堂发布的 8 位游戏机，全球卖了六千多万台，在国内它有个更亲切的名字——小霸王，开机那句“小霸王其乐无穷”是一整代人的童年音效。《超级马里奥兄弟》《魂斗罗》《坦克大战》《冒险岛》，这些游戏本身当然不开源，但让它们跑起来的那台“机器”，逻辑是完全确定的：一颗 6502 处理器、一块逐扫描线画图的 PPU 显像芯片、一颗合成 8-bit 音效的 APU 声音芯片。jsnes 做的事，就是用两千来行核心代码，把这三颗芯片的行为在 JavaScript 里原样推演一遍——ROM 卡带数据进去，画面和声音出来，浏览器就是机箱。

对个人开发者来说，这个仓库的正确打开方式不是“玩”，而是“拆”：它是你能找到的最完整的、可运行的单芯片游戏机参考实现，也是怀旧小游戏这门生意的现成发动机。

核心循环长这样——注意，上头的部分跟 1992 年一模一样，变的只是“开机”这个动作从插卡带变成了刷新网页：

```mermaid
flowchart TD
    A[打开怀旧网页站] --> B[从游戏列表挑一盘童年卡带]
    B --> C[键盘方向键按下即开机]
    C --> D[JS 逐条解释 6502 指令]
    D --> E[Canvas 上屏 + Web Audio 出声]
    E --> F{这一关过了吗}
    F -- 死了命还多 --> G[秒重开 一秒回到当年那把火]
    G --> C
    F -- 过关 --> H[换下一盘 或者换个游戏]
    H --> B
    F -- 打出全服没有的绝活 --> I[录屏分享到群里]
    I --> B
```

## 为什么上头

模拟器本身没有玩法，但它装载的游戏全是最擅长让人“再来一局”的设计。拆开看，怀旧游戏站在今天依然是流量怪兽，靠的是五个钩子：

**第一，上手成本为零的“肌肉记忆遗产”。** FC 游戏难，但你小时候练过的手感还在身体里。别人玩新游戏要教学关，你打开《魂斗罗》直接魂斗罗。这种“上手即巅峰”的体验，是任何新游戏都给不了的——它本质上是把玩家三十年的练习时长，免费充值进了你的网站。

**第二，一局三分钟的短平快。** FC 时代的游戏是按“局”设计的：一条命、一关、几十秒到几分钟。死了立刻重来，没有加载、没有剧情回顾、没有二次确认。这个“死了就按一下”的重开循环，和今天小游戏平台最火的超休闲游戏在节奏上是同一件事，但它自带情怀滤镜。

**第三，游戏列表就是盲盒。** 一个模拟器等于一千款游戏合集。用户进来不是“玩某个游戏”，是“看看还能不能找到当年那盘卡带”。列表每往下滑一行，都是一次开箱抽奖——抽奖抽到的是《雪人兄弟》还是《松鼠大战》，决定了他今晚睡不睡觉。

**第四，补完欲。** 每个玩过 FC 的成年人心里都有一两个“当年没通关”的游戏。没打完的《恶魔城》、没见过的隐藏关、没凑齐的秘密，是三十年前的未完成事件。心理学上这叫蔡格尼克效应，放在产品里这就是天然的用户留存——他不是来玩的，是来还愿的。

**第五，社交货币。** “你看我三十秒过了这关”“这才是原版《坦克大战》的打法”，怀旧内容在微信群和短视频平台是硬通货。模拟器天然适合录屏：像素画面不用加滤镜就是怀旧风，8-bit 音效自带笑点，转发路径极短。

## 技术拆解

这个仓库最值钱的地方，是它把一台游戏机拆成了三节清晰的课，每一节都是可直接复用的组件：

**CPU：一颗 6502 的 JS 解释器。** 取指令、查指令表、执行、扣周期数，标准的解释器循环。所有内存和显存都躺在类型化数组（TypedArray）里，让 JS 引擎按连续内存访问，避开垃圾回收的抖动——这是 JS 写高性能模拟的关键手筋，做任何网页性能敏感型项目都值得抄。

**PPU：扫描线级渲染。** 红白机每帧 256×240，画面是逐扫描线生成的：背景层、精灵层、调色板查找，最后整帧画到 Canvas 上。没有 WebGL、没有着色器，纯 2D Canvas 就能跑满 60 帧——8 位机的画面压力在现代浏览器面前约等于零。如果你的游戏需要“像素风”，这套调色板和精灵逻辑就是现成教材。

**APU：芯片级音乐合成。** 两个方波声道、一个三角波、一个噪声声道，8-bit 音效是数学合成出来的，不是音频文件。把这套思路简化一下，你就能在网页里用 Web Audio 现场合成交互音效，一个音效文件都不用打包——对做小游戏合集的人来说，这是省素材库的神技。

**卡带映射器（Mapper）。** 原版卡带里塞了不同的扩展芯片来突破主机内存限制（MMC1、MMC3 这类主流映射器，jsnes 都有支持）。这层抽象值得看一眼：它本质上是“主板不动、卡带扩展”的插件架构，比现在很多项目的插件设计还干净。

**前端壳子 jsnes-web。** 官方配的 React 壳，做了键盘映射、画面缩放、Web Audio 出声这些脏活。内核和壳子是分开的两个仓库——模拟器是 npm 包，壳子随便换。这意味着你套任何一层皮：公众号网页、小程序 webview、Electron 壳、电视盒子页面，工作量都是周级。

## 变现观察

先说结论：jsnes 本身没有一分钱变现痕迹，它是纯开源的理想主义产物。但围着“浏览器怀旧游戏”这门生意，跑通的路径非常清晰：

**路径一：怀旧游戏合集站 + 广告。** 这是国内外都验证过多年的模式——情怀搜索流量 + 社交转发流量，挂信息流和插屏广告。当年一批 FC 怀旧站靠这个活得很滋润，直到撞上版权墙。

**路径二：官方把模拟器做成订阅。** 最讽刺也最成功的案例是任天堂自己：Switch Online 会员的本质，就是“官方模拟器 + 官方 ROM”做成订阅制。情怀内容 + 低门槛订阅，全球几千万付费会员。个人开发者抄不动任天堂，但“怀旧合集 + 小额订阅/去广告”的结构完全可以缩微复刻。

**路径三：素材安全的 from-scratch 路线。** ROM 版权是这门生意唯一的红线——任天堂对盗版 ROM 的执法是全球出了名的狠，2018 年前后大批 ROM 站直接清库。安全区是 homebrew 社区：全球有一批开发者持续给老主机做全新原创游戏，其中不少以免费或宽松授权发布（itch.io 上能找到一批），拿这些授权卡带做合集站，情怀是真的，法务是干净的。

**路径四：不卖游戏，卖“看懂游戏机”。** 模拟器代码本身就是稀缺教学内容——“两千行 JS 读懂一台游戏机”这种主题，做成付费小册、视频课或者知识星球专栏，面向的是想学底层、想做游戏的开发者，付费意愿比泛流量高一个量级。

对个人的现实排序：路径四 > 路径三的合集站 > 其他。路径一的裸奔模式，今天不建议任何人再碰。

## 给我的灵感

**点子一：授权卡带怀旧站（MVP：1-2 周）。** jsnes 内核 + jsnes-web 壳子 + 从 itch.io 挑 20 款免费授权的 FC 风格 homebrew 游戏，部署成静态站，接广告联盟。技术上几乎零障碍——内核是现成的，你只做选品和皮肤。变现靠广告，跑通后再加“收藏解锁”式小额付费。适合想先练手完整变现闭环的人。

**点子二：童年速通挑战赛（MVP：2-3 周）。** 模拟器有个天然外挂：整局游戏的操作就是一个输入序列，可以完整录制和回放。给它加一个“速通榜 + 回放码分享”——你的通关录像是一串可粘贴的字符串，别人一键看回放、一键挑战同一颗种子。回放码在群里传播就是自增长，变现挂激励视频（看广告解锁对手回放）。这是把单机情怀改造成轻社交的最短路径。

**点子三：换芯不换壳（MVP：3-4 周）。** 壳子留着，内核换开源的掌机模拟器，直接接住“口袋妖怪”级别的情怀流量——搜索量比 FC 还大。注意每个内核的授权条款要过一遍，只上宽松协议的项目。变现路径同点子一，但流量天花板高一档。

**点子四：把 jsnes 拆成一门课（MVP：2 周，纯内容）。** 以这个仓库为教材，做“从零写一个 8-bit 模拟器”系列：第一颗 CPU、第一帧画面、第一声方波。程序员受众、硬核稀缺题材、成品代码就挂在开源仓库里当背书。知识付费对这类“底层原理 + 可运行成品”的内容，付费转化一直不错。

## 上手

- 仓库：https://github.com/bfirsh/jsnes
- 前端壳子：https://github.com/bfirsh/jsnes-web
- 跑起来三步：clone 仓库 → 装依赖起本地服务 → 丢一枚你自己拥有版权的 homebrew ROM 进去。README 里有运行说明，以仓库页面为准。

三十多年前的机器，今天还在给别人发电。你要做的，只是在心脏外面，套一层自己的皮。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
