WebAssembly 游戏开发技术专题全层级31 / 31 已发布

WebAssembly 的十年展望:从浏览器字节码到下一代软件分发基础设施

· 0 分钟阅读
WebAssembly 的十年展望:从浏览器字节码到下一代软件分发基础设施 The Decade Outlook for WebAssembly: From Browser Bytecode to the Next-Gen Software Distribution Infrastructure — WebAssembly 游戏开发技术专题

WebAssembly 的十年展望:从浏览器字节码到下一代软件分发基础设施 The Decade Outlook for WebAssembly: From Browser Bytecode to the Next-Gen Software Distribution Infrastructure

为什么“十年”这个尺度,是判断 Wasm 的第一块基石

这个系列写了二十九篇,拆过编译管道、SIMD、GC、多线程、包管理、供应链安全。到第三十篇,我想换个姿势——不再低头看实现,抬头看看路。

先给自己上一道枷锁:这篇不预测具体产品,只讨论判据。为什么?因为我 2019 年说过一句蠢话,“三年之内浏览器里跑 3A”,现在我的脸还在肿。预测产品的人最后都在打脸,但手里有一套判据,你至少不会被别人的预测带着走。

判据的第一步是选对时间尺度。每次聊到 WebAssembly,讨论都很快滑向“它能不能跑我那个游戏”,然后以一句“性能还是不如原生”收场。这是个错位的问题。技术成熟和生态成熟是两条速度差好几倍的曲线:技术三五年就能成熟,生态要十年。

举几个老例子。Java 1995 年出生,“一次编写到处运行”这句口号真正在业务系统里站住,得到 2005 年之后,中间还隔着一次 JIT 技术的翻身仗。容器的祖宗 chroot 1979 年就有,LXC 是 2008 年,Docker 是 2013 年——从一个系统调用混成一个行业习惯,三十四年。反向的例子也有:Flash 1996 年出生,2005 年被 YouTube 扶正,九年;2010 年被乔布斯那封公开信钉在墙上,到 2020 年正式断气,又是十年。

基础设施这条路上,八岁是个尴尬的年纪。Wasm 2017 年发布 MVP,到今天八年。八年里它完成了一次从“浏览器性能补丁”到“通用运行时”的转身,但还没走完“成为基础设施”的最后一段。这一段最慢,也最容易被误判——因为它的进展不在技术新闻里,在部署文档、包注册表和运维手册里。

所以这篇我想干三件事:把 Wasm 的十年切成三段,看清每段真正会变的是什么;把“Wasm 取代容器”这句流行话拆开,告诉你哪一半是真的;最后给独立开发者一个我敢负责的建议——你现在该往这件事上投多少小时。

第 1 层:Wasm 已经换过三次身份,你的印象多半停在第一次

先把时间线立起来。很多人对 Wasm 的认知还停在“一种让 C++ 在浏览器里跑得更快的格式”,这印象不算错,但它是 2019 年的版本。八年间这东西换过三次身份,每次都改写了“它能拿来干什么”。

第一次身份:浏览器里的汇编(2017—2019)。那会儿的 Wasm 只有一个使命——接 asm.js 的班,把“用 C/C++ 写的东西搬到浏览器”这条路修平。它的自我定位极朴素:一个编译目标,一个比 JS 更容易预测性能的执行格式。这个定位有个隐藏限制:你得先有一个 C/C++ 写的引擎,否则这事和你没关系。Unity 和虚幻是那个阶段的主角,独立开发者基本是围观群众。

第二次身份:走出浏览器的可移植运行时(2019—2023)。WASI 是这个转折点,第三篇里拆过。这里只强调一件事,因为它决定了后面所有事:WASI 的安全模型和 Linux 是反着来的。Linux 默认你有全部权限,然后一层层往下收——用 namespace 隔离、用 seccomp 过滤系统调用、用 capability 切权。WASI 默认你什么都没有,然后你申请一张票据,运行时审核后发给你一张。前者是“入场随便,事后查票”,后者是“入场检票,没票寸步难行”。

这个差别听着像学术洁癖,实际决定谁能用 Wasm 做生意。你愿意在自己服务器上跑一个陌生人上传的模组吗?Linux 那边你得先琢磨怎么把它关进笼子;Wasm 这边,它出生就在笼子里。

第三次身份:可组合的组件(2024 之后)。Component Model 是这次的核心,第十二篇里细讲过。用一句话概括:在它之前,Wasm 是“一个能跑的文件”;在它之后,Wasm 是“一套能对接的插头”。

为什么“插头”对游戏行业格外重要?因为游戏是世界上最古老的模组文化土壤。从 DOOM 的 WAD 到 Minecraft 的 Java Mod,从魔兽的 Lua 插件到 Roblox 的 Luau 脚本——玩家写代码改游戏这件事,撑起了无数游戏的第二春。但它一直有一笔沉重的税:为了支持模组,你得在游戏里内嵌一个脚本运行时,然后自己维护它的沙盒、性能、跨平台兼容,还得祈祷模组作者别把它玩炸。这笔税重到不少小团队干脆放弃模组支持。

Component Model 给了另一条路:模组可以是任何语言写的 Wasm 组件,插件接口用中立方式定义,宿主只暴露它愿意暴露的那几个函数。这是我判断“游戏行业是 Wasm 第二落地场”的核心依据——不是因为它快,是因为它把“信任别人写的代码”这件事的成本打了下来。

说到这儿,得给你一把自己能用的标尺。怎么判断一个技术是“正在成为基础设施”还是“只是个好用的工具”?我总结三条,很土,但好用:

  • 有没有稳定的接口约定。工具可以自己定规矩,基础设施必须有一个第三方都愿意遵守的契约。Wasm 这条刚过半——WASI Preview 2 定了,但生态还在消化期。
  • 有没有独立于宿主语言的包生态。Java 有 Maven,Node 有 npm,容器有镜像仓库。Wasm 这条才起步,warg 还在草案里,WAPM 用起来还是半成品。
  • 有没有第三方愿意为它做工具。这条 Wasm 已经满足得很好——wasmtime、wasmer、wabt、binaryen,一大半不是标准委员会自己做的。

三条过了一条半。所以准确的表述是“Wasm 正在成为基础设施”,而不是“Wasm 是基础设施”。这个区别很重要:它意味着现在入场不算早但也绝对不晚,也意味着任何“Wasm 马上要取代 XX”的说法,你都该先反问一句——那 XX 那套运维语言,谁来补?

第 2 层:短期 1—2 年,先看清已经发生的事,别急着算命

这一层我不预测,我盘点。地基在哪儿,先看清楚,后面的判断才站得住。

落点一:浏览器游戏,能跑这一关已经过了,好跑还没过。

拿 Godot 4 的 Web 导出说事,它是这两年最能说明问题的案例。Godot 4 的 Web 后端是一条完整的 Emscripten 管道:C++ 引擎编成 Wasm,外面裹一层 JS 胶水,再加一个 .pck 资源包。2D 小项目导出后包体起步十几到三十几 MB,3D 项目随资源水涨船高,六十 MB 往上很常见。

包体大不是 Wasm 的锅,是引擎本来就大,Wasm 只是把“大”压到了能接受的加载时间里。真正让开发者半夜骂人的是两件事。

第一件是移动端内存。iOS Safari 对单个标签页的内存预算抠得极狠,社区里一堆血泪案例:同一个 Godot 4 项目,桌面 Chrome 上跑得好好的,上了 iPhone,一进某个场景直接白屏——不是崩溃报错,是浏览器把整个页面回收了,你连日志都捞不着。这件事的残酷之处在于,它不是“性能不够”,是“平台规矩就这么定的”,你优化得再狠也可能撞墙。

第二件是跨源隔离。SharedArrayBuffer 要求页面带上 COOP 和 COEP 两个响应头,这两个头一加,页面里几乎所有第三方资源——广告、统计、字体 CDN、某些图片服务——都得跟着配合。itch.io 的嵌入方案就踩过这个坑,一时间大量 HTML5 游戏在 iframe 里起不来,因为父页面没带这两口锅。

这两个坑放一起,能看出一个规律:Wasm 的技术已经够用了,卡住它的是部署环境的规矩。技术是台好发动机,能不能跑长途取决于加油站和交通法规。未来一两年浏览器游戏这块的主要进展,我认为不在运行时性能上,在工具链和托管平台上——谁能把“跨源隔离”和“内存预算”这两个坑在产品层填平,谁就吃下这块增量。这跟第二十九篇里聊的平台边界之争,是同一件事的两面。

落点二:Ruffle,用 Wasm 给一个死掉的运行时报了仇。

这个案例我特别喜欢,因为它是 Wasm 迄今最漂亮的一次“格式救援”。Ruffle 是 Rust 写的 Flash 模拟器,编译成 Wasm 跑在浏览器里,也有桌面原生版。2020 年底 Flash 正式停运,全世界几十万个用 Flash 做的游戏和小动画面临尴尬:要么留着已经被安全厂商判死刑的 Flash Player,要么逐个重写。

Ruffle 给了第三条路——把整个运行时搬进浏览器,一次性解决。看看它现在走到哪了:Newgrounds、Coolmath Games 这些老牌 Flash 游戏站点已经把 Ruffle 作为默认播放器接进去了。这意味着一个已经“死亡”的格式,靠一个新运行时重新获得了可执行能力。

别把这事理解成复古情怀。它真正证明的是:Wasm 把“把别人的运行时搬过来”的成本,压到了一个小组能承担的量级。Ruffle 的核心团队一直不大,却要覆盖 Flash 的渲染、ActionScript 脚本、音频、输入一整套。换成虚拟机时代的老办法,这个工作量得翻好几倍。

这就是“分发格式”的核心价值——不是最快的,是最省事的那条路。Flash 当年赢不是技术最好,是因为它能在一个浏览器插件里跑任何内容,创作者不用为每个平台做一份。Wasm 现在接的正是这根棒。

落点三:游戏服务端,没人讨论但正在发生。

这块比较闷,但它是真金白银。现在不少游戏服务端是“插件式”架构:核心框架不动,各种玩法逻辑、活动、反作弊规则写成插件挂上去,热更新。这以前是 Lua 的地盘,现在有团队往 Wasm 挪。

为什么值得挪?三个字:多租户。一个平台上的不同游戏、不同玩法、不同用户的脚本共用一套服务器,你不希望任何一个人的代码能把别人的进程搞挂。Wasm 的能力模型天然适合——每个插件只能看到你给它的那几个接口,越界调用的结果是“没有这个函数”,不是“内核崩了”。

这块的进展不会上新闻,它在服务端,玩家看不见。但我认为未来一两年,Wasm 在游戏行业的装机量增长里,服务端这块的占比会超过浏览器游戏。原因很简单:浏览器游戏的天花板被平台规矩锁着,服务端没有这个约束。

第 3 层:中期 3—5 年,模组是 Wasm 在游戏行业最锋利的一把刀

上面三个落点还只是前菜。真正让我觉得这十年值得下注的,是模组。

先把现状摆平。今天做模组支持,基本就三条路,每条都有它的税。

  • 内嵌脚本语言。魔兽用 Lua,Roblox 用 Luau,不少国产 MMO 用 Lua 或 Python。优点明摆着:热更新快、门槛低、玩家改一行代码就能看到效果。缺点也明摆着:性能天花板低,一门语言锁死所有模组作者,而且解释器本身就是一个巨大的攻击面——你想让玩家写代码又不让他拆房子,就得一层层做 API 白名单,做到最后发现自己在给一门完整的编程语言做沙盒。
  • 原生插件。上古卷轴的 SKSE、Minecraft 的 Java Mod、各种 DLL 注入。能力和性能拉满,代价是安全和兼容性灾难:一个模组写崩了,玩家存档就没了;两个模组抢同一个资源,游戏就起不来。
  • 数据驱动的伪模组。只让你改配置表和资源,能力有限但最安全,代价是模组作者的创意空间也被锁死。

Wasm 提供的是第四条路,而且它同时在三个维度上打了补丁。

跨语言,靠 Component Model 和 WIT。旧的 Wasm 模块接口是纯数字的——你传一个整数进去,它返回一个整数,字符串得自己往线性内存里塞、自己管释放、自己处理编码。跨语言对接一次这种接口,能让人掉不少头发。WIT 是接口描述语言,你用中立的方式写“这个函数要一个字符串,返回一个结构体”,剩下的事交给工具去各语言生成绑定。于是模组作者可以用 Rust 写、用 Go 写、用 C# 写,出品都是同一份 Wasm;游戏那边只要认 WIT 这一份接口契约。

能力受限,靠 WASI 的授权模型。模组只能调用宿主明确暴露的那几个函数。这不是“你做错了我就罚你”,是“这件事对你不存在”。这两种安全感完全不同。前者你得想到所有坏事,后者你只需要想清楚该发哪几张票。

崩溃可隔离,靠实例化。一个 Wasm 实例有自己独立的线性内存,它玩崩了自己那几百兆,宿主的堆丝毫不受影响。宿主重开一个实例继续跑,玩家最多看到一次卡顿。

这个方向已经有商业化案例。The Mirror 就是把 UGC 脚本运行时的赌注全压在 Wasm 上的团队,他们的方案能在虚幻、Unity、Godot 三个引擎里跑同一套用户脚本。他们的卖点说白了就一句话:让游戏厂商敢开放 UGC。厂商最怕的不是模组写得烂,是模组把玩家电脑搞坏、或者模组作者闹出版权和安全事故。把模组关进 Wasm 这个笼子里,这件事就变成了一个能写进合同的技术承诺。

但我必须给代价,不然这篇文章就成软文了。

代价一:调试体验仍然是灾难。你在开发者工具里点开一个 Wasm 栈,看到的多半是地址和偏移。DWARF 调试信息能救一部分,但模组作者通常拿不到你游戏编译产物的符号,这条链路至今不通。玩家一个模组报错,你得像侦探一样反推,这是实打实的人力成本。

代价二:跨边界调用是有价格的。每次从宿主进 Wasm、或从 Wasm 回宿主,都是一次“翻译”。单次开销很小,小到不测量基本感觉不到;但如果它落在热路径上(比如每帧调用上千次),这点开销会攒成卡顿。我的经验判据是:每秒跨边界调用超过十万次这个量级,就该重新设计接口,把批量数据攒起来一次性传过去。这个数字是我自己踩坑踩出来的粗略感觉,不是标准,别当圣旨。

代价三:开发体验不如脚本语言。Lua 模组改一行存盘就能看到效果,Wasm 模组改一行要重编译。Rust 的增量编译现在已经很不错,但对“边玩边调”这种模组作者最爱的工作方式来说,还是慢半拍。这是真实门槛,会让一部分轻量模组作者望而却步。

所以我的判断是:Wasm 不会把所有游戏模组都吃掉,它会吃掉“需要性能 + 需要跨平台 + 需要安全”的那一块——大型 Mod、官方支持的 UGC 平台、带商业分成的创作者生态。轻量的数据驱动模组会继续留在配置表里,这没什么不好。一个游戏里同时存在两种模组形态,未来几年可能是挺常见的画面。

第 4 层:长期 5—10 年,Wasm 取代容器?先问一句“运维谁来管”

到了这篇文章最容易写飘的部分。每次看到“Wasm 要取代 Docker”的标题,我心里都会响起一句老话:卖铲子的永远比挖金子的乐观。

先把支持者的牌摆出来,他们的牌不算差。

  • 冷启动。Wasm 实例化是毫秒级,容器从镜像到进程起来是几百毫秒到几秒,差两个数量级。
  • 密度。一台机器跑几千个 Wasm 实例不新鲜,容器跑到几十上百就开始抖。
  • 安全模型更细。容器是“系统调用过滤”,Wasm 是“我只给了你这些函数”。
  • 跨架构。一份 Wasm 在 x86、ARM、RISC-V 上都能跑,容器镜像得分架构。

这些都对。但它们回答的是“哪个跑得快、跑得密”,没回答“哪个能管”。基础设施的胜负经常不在性能上,在谁能让运维睡得着觉。

缺一:没有真正的进程模型。容器里一个进程崩了,内核帮你收尸,你有信号、有退出码、有僵尸进程回收。Wasm 实例崩了,宿主得自己决定重不重启、怎么隔离、怎么计数。这不是“能不能做”的问题,是“每个运行时厂商都在自己发明一套”的问题。生态在这一层是碎的。

缺二:网络栈还在襁褓。WASI 的网络接口到现在还是早期。游戏服务器要的是什么?UDP、NAT 穿透、长连接、对 epoll 那种细粒度的控制权。这些在 Wasm 这边还是一堆正在吵的提案,而 Linux 那边是二十年打磨出来的东西。

缺三:可观测性。容器世界有 cgroup、有 eBPF、有 strace、有各种 sidecar。运维工程师爱这些东西,因为它们让“线上出事了”变成“我能查”。Wasm 这边你能拿到的还是“这个实例吃了多少内存”。查不了的东西,不敢上生产。

缺四:生态惯性。镜像仓库里几百万个镜像,不是一天建起来的,也不是一天能被取代的。

反过来也得给 Wasm 说句公道话:有件事容器做不到,就是“把别人的一段逻辑嵌进我的程序里”。容器的粒度是进程,Wasm 的粒度是函数。前者你要么整台机器给它,要么不给;后者你可以只把这一个函数交给它,剩下的继续自己管。这个粒度差异,对“游戏里跑玩家写的代码”这个场景是降维打击。

所以结论四个字:不是取代,是分流。

维度容器继续擅长的Wasm 会吃掉的
生命周期长期运行的有状态服务短命、事件驱动、一次性的计算
依赖依赖特定内核、驱动、系统库纯逻辑、无系统依赖
租户模型一租户一容器一租户一实例或一函数
运维成熟的可观测性工具链还在补课

而且这俩不是敌人,是会互相嵌入的。Docker 早就宣布支持 Wasm 了,这不是认输,是想做那个“不管里面跑的是什么,包格式都归我”的角色。第二十二篇聊 OCI 与 Wasm 容器化的时候,说的就是这件事。

对独立游戏开发者,这条判断落到具体场景是什么?如果你的服务器模型是“一房间一进程”——不少独立联机游戏就是这样——Wasm 的吸引力是真实的:房间结束就销毁,内存回收干净,密度高、冷启动快,还能顺手把玩家上传的自定义玩法隔离掉。但上手之前,先把三个问题问清楚:你的房间逻辑要不要 UDP?要不要长连接?要不要连数据库?这三个答案,可能直接决定你是在省事还是在找事。

参数化工具:三张表,帮你决定投不投、投多少

展望文章最容易变成空话,所以给三张能直接用的表。数字是我根据公开信息和自己项目经验拍的,你可以拿去改,但别当精确值用。

表一:游戏视角的 Wasm 能力成熟度雷达

应用场景2025 现状2027 预期2030 预期我的置信度
桌面浏览器跑游戏成熟成熟成熟高
移动端浏览器跑游戏半成熟(内存坑多)半成熟成熟中
游戏服务端玩法插件起步可用成熟中
UGC / 模组沙盒起步可用成熟高
编辑器与工具链插件可用成熟成熟高
主机平台脚本运行时不成熟起步可用低

“置信度”这一列是这张表的灵魂。我给主机平台打“低”,是因为这件事的技术障碍其实不大——第二十三篇里说过的那些嵌入式运行时早有案例——真正卡住它的是平台方的认证流程和商业意愿。技术问题我可以拍脑袋,商业问题我不敢。

表二:你该往这上面投多少小时

你的角色每周投入学什么回报周期
纯单机独立开发0—2 小时把引擎的 Web 导出跑通就行半年内(多一个试玩渠道)
有 UGC / 模组计划3—5 小时组件模型 + 一个运行时嵌进主程序6—12 个月
要做联机后端 / 服务端5—8 小时WASI 能力模型 + 边缘部署 + 插件隔离设计6—18 个月
纯技术兴趣随意随便玩,这行当的乐趣本来就在折腾不一定

我给大多数独立开发者的建议是:每周 2—5 小时,占你总学习时间不超过两成。理由是 Wasm 现在是“能力储备”,不是“救命稻草”——它不会让你的游戏立刻变好,但会在你需要做模组、做服务端、做跨平台时,让你少走三个月弯路。

表三:这个功能该不该用 Wasm

你的需求结论为什么
要让玩家用多种语言写模组该用这是 Wasm 目前最没有替代方案的地方
要在自己服务器跑不可信代码该用能力模型比自建沙盒靠谱得多
只是想让浏览器里跑得更快先量,别猜多半是渲染或资源加载的锅,不是执行速度
要访问串口、文件锁、特定系统接口别用WASI 在这些方向还很嫩,会把你逼疯
要在主机上跑脚本先问平台方技术在,认证流程不在

这三张表真用起来你会发现,最有价值的是“置信度”和“别用”这两列。做技术的容易陷入“能做的都要做”,但技术选型里最值钱的能力,是知道什么不做。

双路径:两种读法的入口

初级用户速览:三个结论,五分钟看完

第一,Wasm 早就不是“浏览器里跑 C++ 的加速器”了。它现在是跨平台的运行时格式,能跑在浏览器、服务器、边缘节点,甚至单片机上。你对它的印象如果还停在 2019 年,是时候更新一下。

第二,未来三年它最大的游戏机会不在“取代原生”,在两件很闷的事上:让游戏支持跨语言模组,和让服务器能安全地跑别人的逻辑。这两件都不性感,但都能省钱。

第三,你现在该学的不是指令集,是接口设计。Wasm 的坑九成都在“边界”上——什么数据传进去、什么数据传出来、谁负责释放内存、一次调用值多少钱。学会怎么划这条边界,你换任何一个运行时都用得上。

想今天就动手,我给条路径:找一个你熟悉的引擎(Godot 最轻),把它的 Web 导出跑通。跑不动就看控制台报什么错,把那两个跨源隔离的响应头搞明白。这一步大概半天,能让你对“部署环境的规矩”有体感,比看十篇文章管用。

进阶深入:把 Wasm 当架构问题,不是技术问题

如果你已经在做服务端或插件系统,建议换个视角:Wasm 不是“一个更快的东西”,它是“一个给代码划边界的工具”。围绕这个视角,有几个问题值得先想清楚。

你的系统里,哪一部分是“接口稳定、内部可以随便换”的?那部分最适合切出来变成 Wasm 模块。反过来,那些需要频繁访问宿主数据结构、需要共享大量状态的地方,塞进 Wasm 只会让你被序列化和跨边界调用折磨。

谁来管内存?Wasm 有独立的线性内存,跟宿主的堆是两回事。这意味着每一份跨边界的数据,都得有一方负责“复制过去”和“什么时候能释放”。设计得不好,你会同时拥有两种风格的内存泄漏,修起来双倍快乐。

你的调用预算多少?我一般先算一笔账:这个功能每秒跨边界多少次、每次大概多少开销、加起来吃不吃得掉这一帧的时间预算。算完经常发现,本来想优化性能,结果加了一堆调用开销。所以顺序永远是先测量、再动手。

调试链路要提前想。报错的时候你能不能看到模组作者的源码行号?日志能不能区分“宿主崩了”和“模组崩了”?这些设计阶段不做,上线后就是无穷的客服工单。

常见坑与争议:这四件事我劝你别信

坑一:把性能当成分发的理由。“Wasm 快,所以它会取代原生游戏”——这条推理链中间断了一节。分发的胜负从来不是性能决定的,是兼容性和维护成本。Flash 赢的时候性能稀烂,赢在“哪都能跑”。反过来,性能不能帮你赢,但性能差能让你输得很难看。Wasm 在浏览器游戏上的天花板,主要被内存和加载时间卡着,不是执行速度。

坑二:“能编译”就等于“能用”。Emscripten 确实能把一大堆 C++ 编到 Wasm,但那只是第一步。编出来之后,你得管内存、管线程、管资源加载、管文件系统的模拟。我见过太多团队在“编译成功”那一刻欢呼,然后在“跑起来像 PPT”那一刻沉默。

坑三:以为 Wasm 沙盒是万能的。这是最容易翻车的一条。Wasm 保证了内存安全,但它不保证你的服务不被打死。一个恶意模组写个死循环,你的线程就被它占住;写个疯狂吃内存的循环,你的进程就得 OOM。这些在安全圈叫拒绝服务,Wasm 规范管不了,得靠宿主做超时、做内存配额、做调用次数限制。侧信道那摊事——第二十篇里说过的 Spectre 残留风险——也一样,沙盒边界挡不住时间攻击。

坑四:赌“十年后”的技术选型。这是我最想劝住的一条。你现在的项目等不到 2030 年。如果一个方案需要“等行业再成熟三年”才能用,那它对你现在这个项目就等于不可用。判断标准很简单:这件事今天能不能在你机器上跑通?跑不通,就放进备选池,别放进路线图。

还有个争议我想摊开说:Wasm 会不会像 Flash 一样死掉?

我的看法是可能性很低,但理由可能和你想的不一样。不是因为 Wasm 技术更好——Flash 当年技术也不差——是因为 Wasm 从来没有一家公司拥有它。它躺在标准社区组和字节码联盟里,Mozilla、Google、微软、英特尔、Fastly 各有各的算盘,谁都掐不死谁。第二十六篇拆过这套权力结构,那里面的博弈很难看,但难看恰恰是它活得久的原因。

真正值得担心的是另一件事:标准越做越大,实现跟不上。GC、异常处理、尾调用、多内存、组件模型,一堆提案同时在飞。大厂有资源跟,小运行时跟不上,最后生态会分层——大运行时什么都有但很重,小运行时轻但缺特性。这个分层本身不是坏事,但它会让“一次编写到处运行”这句老话再打一次折扣,就像 Java 当年那样。

FAQ

Q1:我现在才开始学 Wasm,是不是晚了?

不晚,甚至可以说刚好。技术已经过了“学它没活干”的阶段,生态还没到“不学就没饭吃”的阶段——这个窗口期最舒服,学的东西能落地,又不用被赶着跑。真要担心的不是晚,是学错方向:别一上来啃指令集和二进制格式,先学怎么设计边界、怎么选运行时、怎么测量开销。这三样才是日常用得上的。

Q2:我只用 Unity 或 Godot,需要懂 Wasm 吗?

看你做多大。如果你的游戏永远不碰 Web 导出、不碰模组、不碰自建服务端,那确实可以一辈子不懂,引擎会替你扛。但只要碰到其中一样,你就会在某个深夜发现,报错信息全部指向一层你不认识的东西。到那时候补课的代价,比现在每周花两小时高得多。我的建议是:至少懂到“知道它在哪一层、出错该找谁”这个程度,这是止损线,不是上限。

Q3:Wasm 会不会像 Flash 一样,被某家公司一刀切死?

结构上很难。Flash 的死因是“一家公司同时拥有格式、运行时和分发入口”,它想让你死你就得死。Wasm 这三样是分开的:格式在标准组织手里,运行时有一堆厂商在竞争,分发入口散落在各家 CDN 和平台上。没有单点,就没有单点故障。真正的风险不在被掐死,在标准膨胀导致的实现分裂,前面说过。

Q4:“Wasm 取代 Docker”这个说法,我该信几成?

信两成。那两成是真的:短命、无状态、多租户的计算场景,Wasm 确实比容器划算,冷启动和密度优势是数量级的。剩下八成不能信,因为那些场景要的不是“跑得快”,是“出事了能查、能限流、能审计、能迁移”,这一整套运维语言 Wasm 还在补。更现实的画面不是取代,而是“你的容器里跑着一个 Wasm 运行时”。

Q5:做独立游戏,应该 Web 优先还是原生优先?

取决于你的游戏是什么,但给一个粗暴判据:如果你的游戏靠“随时随地打开就能玩”获得传播,Web 优先;如果靠“沉浸几个小时不被打断”获得口碑,原生优先,Web 只当试玩渠道。Wasm 让这两个选项不再互斥——同一套逻辑可以两边跑,但你要为它付出额外工程成本,这笔账得自己算。

Q6:那我现在到底该不该把模组系统改成 Wasm 版?

先回答一个问题:你现在的模组系统,是被“安全问题”卡住了,还是被“没人写”卡住了?前者值得改,后者改了也没用。我见过不少团队花三个月做了一套很漂亮的沙盒,上线一年只有七个模组,其中三个是自己人写的。模组生态的核心从来是“有没有人愿意写”和“写了有没有人玩”,技术方案是第八位的事。

写在三十篇之后:别问取代谁,问什么变便宜了

这个三十篇的系列到这儿收尾了。回头看,Wasm 这八年真正干成的事,不是“让网页变快”,是把“运行别人写的代码”这件事的成本压到了前所未有的低点。低到你可以让玩家写模组,低到你能在一台机器上塞几千个租户,低到一个小组能把一个死掉的运行时整个搬进浏览器里复活。

至于十年后会怎样,我给不了答案,只能给一个观察角度:别问“Wasm 会不会取代 X”,问“Wasm 让哪件事变便宜了,便宜到原本不划算的生意现在划算了”。前一个问题供人吵架,后一个问题供人赚钱。

最后留个问题给你:如果明天开始,你手里有一个免费的、跨语言的、安全的沙盒,可以跑任何玩家写的代码——你会在自己的游戏里开放什么?是自定义玩法?是 UI?还是干脆把整个游戏逻辑都交出去,你只提供一个世界?这个问题没有标准答案,但它比“Wasm 快不快”有意思得多。

文章标签
WebAssemblyWasmEmscriptenWASIwasm-bindgenComponent ModelSharedArrayBufferAtomicsWasm 多线程Wasm SIMDwasm-packRust Wasm
更多专题全部专题
觉得有价值?点赞或收藏支持内容持续产出。
← 返回专题:WebAssembly 游戏开发技术专题