我先不按老套的“教程”写法来,直接以一个折腾过的过来人口吻聊聊。
如果你在 GitHub、独立游戏社区、或者某个深夜的技术论坛里刷到过 “Superpowers” 这个词,大概率看到的不是一个夸夸其谈的励志概念,而是一个能真正跑起来、能多人实时一起写代码做游戏的开源项目。很多人第一次看到它的第一反应是:这玩意儿到底是个游戏引擎,还是一个在线 IDE?我当初也是带着这个疑问下载的,然后被它“打开浏览器就能用一个团队做个 2D/3D 游戏”的设定惊了一下。这篇文章就完整梳理一下:Superpowers 到底能干嘛、怎么装、怎么上手,以及我踩过哪些坑。
1. Superpowers 是什么——藏在浏览器里的多人游戏开发环境
1.1 一个能多人实时协作的“云游戏工作台”
Superpowers 是一个基于 Web 的开源游戏制作平台,核心思路是把“游戏引擎”和“开发编辑器”全部塞进浏览器里。它由法国的开发者 Florian F迹象(网络 ID 是 spasimir)发起,代码托管在 GitHub 上的 superpowers-org 仓库里,整个项目用 TypeScript 写成,客户端通过浏览器访问,服务端在本地或你自己的服务器上跑。你不用安装 Visual Studio、不用装 Unity Hub、不用配 Node 开发环境,只要有一个现代浏览器,打开服务地址,就能进入一个完整的项目编辑器。
最特别的是多人实时协作:几个人同时打开同一个 Superpowers 项目,每个人都能看到别人正在拖拽的场景、正在修改的脚本、正在调整的资产。这种体验更像是 Google Docs 套到了游戏引擎上,而不是传统的“一个人改完推 Git,另一个人 pull 下来继续改”。对于做 Game Jam、远程教学、或者小团队快速原型验证来说,这个特性真的能省掉一大把沟通成本。
1.2 底层逻辑:浏览器是壳,Lua 是脑子,Three.js 是手
Superpowers 的渲染层基于 Three.js,场景里的模型、精灵、摄像机、灯光都是 Three.js 的对象。
但写游戏逻辑用的不是 JavaScript 或 TypeScript,而是一种内嵌的 Lua 脚本环境。每个游戏对象(Entity)上可以挂多个组件(Component),组件里写 Lua 脚本来控制行为。比如你创建一个精灵(Sprite)显示一张图片,再挂一个“自定义脚本”组件,在脚本里写键盘监听和坐标运算,就能控制这个精灵移动。
Superpowers 帮你把“引擎内核”和“编辑器”深度耦合在一起。你不用去关心 WebGL 上下文怎么建、Asset 怎么打包、合批渲染怎么做,这些都被封装在平台内部。你只需要关注:场景里放什么,物体怎么动,逻辑怎么触发。
这种设计有很大优势:用户不需要处理工具链。做 HTML5 游戏最痛苦的往往不是写逻辑,而是配构建环境、处理资源加载、解决跨域问题。Superpowers 把这一层直接收走了,你在编辑器里按一下播放,就能立刻预览游戏效果,浏览器本身就是运行时,所见即所得。
2. 为什么值得安装和尝试
2.1 找个人一起写代码,不再靠改文件传来传去
以往两个人合作做一个网页游戏,最常见的协作方式是:一个人写好代码推 Git,另一个人拉下来跑,遇到冲突再费劲解决。如果只是临时想调一个玩法原型,这种协作成本高得离谱。
Superpowers 的多人协作是“同时编辑”级别的。我自己实测过:一台电脑上跑服务,局域网里用另一台电脑开浏览器进去,两个人同时对一个项目做修改,操作延迟很低。它的同步是通过服务端广播文档变化来实现的,每个人编辑的文档像协作文档一样被合并。正因为整个编辑器本身就是 Web 应用,所有操作都是对数据模型的修改,所以天然适合实时同步。
2.2 零安装、跨平台、开箱即用的“轻引擎”
传统游戏引擎普遍“重”:Unity 装完十几个 GB,Unreal 更是重量级,想开个 3D 工程电脑风扇转得跟起飞一样。Superpowers 本体只有几十 MB,下载解压后直接运行。无论你是 Windows、macOS 还是 Linux,只要有浏览器就能开始做项目。
远程服务器部署也很方便:把 Superpowers 装到一台 2C2G 的小云主机上,团队成员从世界各地访问同一个地址,就能一起干活。这意味着你只需要一个轻量服务器,就拥有了一套“在线游戏开发环境”,不需要给每个人配高配电脑,也不需要集中式地安装软件。
2.3 适合谁:Game Jam 团队、编程教学、原型快速验证
从应用场景来说,我实际用下来觉得最合适的是三类人:
- Game Jam 爱好者:48 小时内要出一个可玩的游戏,没有时间磨工具链,几个人同时上手改东西效率极高。
- 编程教学者/学习者:学生不需要装环境,老师开一个服务,所有人浏览器进入同一个项目,教学演示和动手练习无缝衔接。
- 独立开发者做原型验证:想快速验证一个玩法点子是否有趣,用 Superpowers 搭场景加脚本,比用重型引擎快得多。
3. 安装 Superpowers 的完整实操
3.1 Windows 本机部署:下载、解压、启动
Superpowers 的发布包托管在 GitHub Releases 页面,你搜 “superpowers-org/superpowers” 就能找到。下载对应你系统的压缩包,Windows 一般选superpowers-x.x.x-win64.zip这种文件。
下载完解压到一个没有中文和空格的目录,比如D:\dev\superpowers,然后进入目录找到可执行文件:
- Windows 下直接运行
Superpowers.exe - macOS 下运行
Superpowers.app或对应的二进制 - Linux 下运行
Superpowers可执行文件
启动后终端会打印一行服务地址,默认是http://localhost:4237。打开浏览器访问这个地址,第一次会让你创建管理员账号,创建完就能进入项目管理界面。
3.2 服务器部署:用 npm 装,用进程守护跑起来
如果你想把 Superpowers 部署到云服务器上,推荐用 npm 方式安装。前提是服务器上已经有 Node.js(建议 18 以上版本)和 npm。
npm install -g superpowers装完以后直接运行:
superpowers默认监听 4237 端口。这时你可以在本机访问,但要让团队成员访问,还要解决端口、防火墙和反向代理的问题。我的建议是用 Nginx 把 4237 端口代理到 80 或 443,同时开启 WebSocket 支持。
一个适合生产部署用的配置片段:
server { listen 80; server_name your-domain.com; location / { proxy_pass http://127.0.0.1:4237; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }注意proxy_set_header Connection "upgrade"不能漏。Superpowers 的实时协作依赖 WebSocket,如果 Nginx 没把 Upgrade 请求转发对,会出现打开编辑器后一直连不上服务、场景加载不出来的情况。
还可以用 systemd 把 Superpowers 注册成系统服务,避免终端一关服务就没了。
3.3 启动参数和数据存储
Superpowers 服务本身有一些可调参数,常用的有端口和 host:
superpowers --port 8080 --host 0.0.0.0--host 0.0.0.0可以让服务器监听所有网卡地址,这样局域网或公网的设备才能访问到。只在本机调试时不用加,保持默认即可。
所有项目的数据、用户账户、资源配置都存储在服务端的本地文件系统里,Windows 下通常在执行文件所在目录的superpowers数据文件夹内。建议定期备份这份数据,它就是你的全部项目资产。具体来说,可以打包整个数据目录存到云盘或 Git 仓库私有库,至少让我免于一次服务器磁盘损坏后全部工程丢失的悲剧。
3.4 浏览器兼容性
实测下来,Chrome 和 Edge 的体验最稳,Firefox 也可以,但部分高级插件在 Safari 下会有显示问题。开发时期建议统一用 Chromium 内核浏览器,免得排查问题时分不清是代码问题还是浏览器兼容问题。
4. 从零做一个可玩的 2D 小游戏
4.1 创建项目:从空白到场景
安装完服务后,用浏览器进入管理界面,点击“新建项目”,输入项目名称,选择 2D 模板(当然也可以选 3D,我们这里先用 2D 最简单)。创建后进入主编辑器界面。
界面主要分三块:左边是资源浏览器(Assets),中间是场景视图(Scene),右边是属性检查器(Inspector),底部是控制台和输出。如果用过 Unity,这套布局零学习成本,基本是同类布局。
创建项目后,场景里默认有一个“Camera(摄像机)”对象。在 2D 模式下,摄像机决定了你能看到的世界范围,这一点和所有 2D 游戏引擎一致。
4.2 添加一个玩家精灵
接下来我们要让屏幕上出现一个可以控制的绿色方块。
第一步:在资源区新建一个“Sprite”资源,选择一个简单图片。Superpowers 支持直接拖入图片文件到资源区,也可以创建内置的图形资源。为了省事,可以直接创建一个纯色材质。
第二步:在“场景”根节点下右键,选择“创建对象 -> Sprite”,一个精灵对象就出现在场景中。在属性检查器里把它的 Sprite 资源指向刚才创建的素材。
第三步:在属性检查器中找到“Transform(变换)”组件,把位置设置在画面左下角附近,比如x=-4, y=-3。
这样画面上已经能看到一个方块了。点击顶部播放按钮,方块就在那里,但还不会动。
4.3 用 Lua 写第一段控制脚本
现在给方块加上移动逻辑。选中方块对象,在属性检查器中点击“添加组件”,选择“脚本(Script)”,它会创建一个.script文件资源。双击资源区里的这个脚本文件,打开内置的 Lua 代码编辑器。
Superpowers 的 Lua 脚本模板通常长这样:
function onInit() -- 初始化逻辑,对象创建后调用 end function onUpdate(dt) -- 每帧更新,dt 是距上一帧的时间差 end要实现方向键移动,我直接给出一个最简版本:
local speed = 4 function onInit() -- 可以在这里初始化变量 end function onUpdate(dt) if Keyboard.isDown("ArrowLeft") then this.position.x = this.position.x - speed * dt end if Keyboard.isDown("ArrowRight") then this.position.x = this.position.x + speed * dt end if Keyboard.isDown("ArrowUp") then this.position.y = this.position.y + speed * dt end if Keyboard.isDown("ArrowDown") then this.position.y = this.position.y - speed * dt end end脚本里的this指向当前对象。通过this.position拿到 Transform 组件,直接修改x和y就能移动对象。
写完保存脚本,回到场景视图,点击播放键,按方向键,方块就能移动了。
这里有个细节很多新手会忽略:Saved in scene(脚本保存)后,场景里对象的属性修改也要记得保存场景本身。Superpowers 的编辑器和资源是分离的,如果你改了脚本但没保存场景(Ctrl+S),关闭页面后改动可能丢失。我一开始就吃亏在这里,明明脚本写了,重新打开后对象上挂的脚本引用是空的,后来才反应过来要额外保存场景文件。
4.4 摄像机跟随与边界约束
想让玩家的活动范围更大,就需要摄像机跟随玩家。
在场景里找到摄像机对象,给它添加脚本:
local target -- 要跟随的目标 local cameraMaxX = 8 local cameraMaxY = 5 function onInit() -- 通过名称寻找场景里的目标对象 target = Scene.findOne("player") end function onUpdate(dt) if target then local pos = target.position local camPos = this.position camPos.x = pos.x camPos.y = pos.y end endScene.findOne("player")是 Superpowers 内置 API,可以在场景中按对象名查找对象。我在实际项目中更推荐把目标对象通过编辑器拖拽绑定到变量上,而不是在代码里查找,因为一旦改名字,脚本就会找不到对象。但快速原型阶段上述写法足够。
当然,如果不想让摄像机无限跟随,你可以做一个简单的边界束缚:摄像机位置只在 -8 到 8 之间移动,避免把空白区域也带进视野。这个根据自己的游戏需求灵活调整。
到这里,一个能移动、摄像机跟随的 2D 小场景已经有了雏形。剩下的就是加敌人、加碰撞、加得分逻辑。
5. 常见问题与排查技巧实录
5.1 端口被占用怎么办?
Superpowers 默认端口是 4237。如果你启动时报错端口被占用,可能是别的服务占了这个端口。两个解决思路:
- 直接换端口:
superpowers --port 5000 - 找到占用进程:Windows 下
netstat -ano | findstr 4237,拿到 PID 后去任务管理器结束进程;Linux/macOS 下lsof -i :4237。
个人经验:与其去杀进程,不如直接换端口。省得误杀别的服务。
5.2 编辑器一直显示“正在连接服务器”
出现这个大概率是 Nginx 反向代理没配 WebSocket。虽然页面能打开,编辑器的实时通道建立不起来,所有场景数据拉不下来。
把 Nginx 配置里那段Upgrade和Connection "upgrade"补上,然后nginx -s reload重新加载。我遇到过一次死活配不上的情况,最后发现是防火墙把 443 端口的 WebSocket 升级请求拦了,放行端口后就好了。
5.3 多人协作时对方看不到我的操作
先确认所有人访问的是同一个地址。如果一个人用 IP 访问、一个人用域名访问,Superpowers 会识别成“不同来源”,协作同步可能异常。
再检查浏览器控制台有没有报错,尤其是 WebSocket 报错。如果双方都在局域网内,直接都用http://局域网IP:4237访问,不要混用 localhost 和 IP。
5.4 脚本报错后游戏一直黑屏或停止
脚本里一旦出现运行时错误,比如调用了未定义的函数、引用了空对象,播放状态会直接停下来。
排查方法:先看底部“控制台”里输出到哪一行断掉,把 Lua 代码里对应的逻辑注释掉,再逐步还原。建议养成好习惯:每个onUpdate里的逻辑都做空值判断,尤其当对象可能被销毁时,避免下一帧访问空引用。
5.5 资源文件中文名或特殊字符导致异常
Superpowers 对资源命名虽然支持中文,但在某些操作系统组合下,文件名含中文或空格可能会让资源引用失效。最稳妥的做法是资源命名统一用小写英文加下划线,比如player_icon.png。虽然有点土,但不会出幺蛾子。
5.6 数据备份与迁移
Superpowers 的项目数据全在服务端目录。迁移服务器时,只需要停掉服务,把数据目录打包传到新服务器,重新启动 Superpowers,它就能识别出所有项目,像什么都没发生过一样继续运行。
我在迁移时踩过一次坑:只拷贝了执行文件没拷贝数据目录,新服务器打开是空白面板,还以为装错了版本,后来反应过来数据根本不在执行文件里。这类“数据目录和程序分离”的设计很容易让人误判。
6. 对 Superpowers 的扩展玩法与个人展望
除了做常规的 2D/3D 游戏,Superpowers 的开放架构还支持编写“插件(Plugin)”。你可以在 web app 目录里用 TypeScript 开发新的组件类型、新增资源类型、甚至扩展编辑器 UI。这个特性非常适合想深入了解引擎内部实现的开发者:你用的编辑器本身就是一个 Web 应用,改的是 TypeScript 源码,调试思路跟平时写前端一模一样。
我在接触一段时间后,最大的感叹是:它把一个“重型引擎才有的多人协作能力”做成了轻量级开箱即用的形态。虽然生态和商业引擎没法比,但如果你做的是独立小游戏、教学演示、或者想快速验证玩法,Superpowers 提供的“零安装 + 多人协作”的组合拳,实际使用体验非常独特。
如果你也想尝试,我个人推荐的路径是:先在本机跑起来,用模板做一个 10 分钟内能完成的移动小球,感受一下编辑器和脚本的配合方式,再拉一个朋友进来试多人协作,最后才考虑部署到服务器长期使用。这样既能快速理解它的核心机制,也不至于一上来就被各种概念绕晕。
Superpowers 不一定成为你的主力引擎,但作为一套“打开浏览器就能开始创作”的工具,它值得每个喜欢捣鼓游戏开发的人尝试一次。