npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@graviton-game/bevy-minigame-kit

v0.1.0

Published

Bevy Adapter for Wechat Mini Game: build pipeline, wx-env mock and simulator verification for Rust->wasm games

Readme

bevy-minigame-kit

Bevy Adapter for Wechat Minigame(微信小游戏)——把 Bevy(Rust → wasm-bindgen → wgpu WebGL2)跑进微信小游戏运行时的适配层。当前处于可行性验证 spike 阶段。

  • 可行性研究报告与参考实现(bevy_gamekit)深挖笔记:docs/reference-bevy-gamekit.md
  • 总体结论:条件性可行。Android(微信 8.0.24+/基础库 2.24+)走 WebGL2; iOS 需高性能/高性能+模式(game.json iOSHighPerformance: true + 平台开通)
  • 完整游戏示例:bevy-minigame-example——三消 (bevy-match-3 上游移植,含 bevy_state/picking/ui 新验证面与 wx 音频桥), 已在 Node mock / 浏览器基线 / 开发者工具模拟器三环境验证通过

里程碑状态

| 阶段 | 内容 | 状态 | |---|---|---| | S1 | 纯 wasm 链路(glue patch + WXWebAssembly + 环境垫片) | ✅ Node mock 双场景通过 | | S2 | Bevy 0.20 第一帧(完整垫片层 + wgpu WebGL2) | ✅ Node mock 通过 + 浏览器基线 + 开发者工具模拟器验证通过 | | S3 | 触摸输入 + 体积数据 | ✅ 浏览器基线鼠标跟随像素级验证 + mock 触摸探针 + 模拟器拖拽跟随验证 | | S4 | 微信开发者工具 / 真机验证 | ✅ 模拟器全项通过(启动/渲染/拖拽/切后台/内存曲线,见 docs/devtools-verification.md);真机扫码待人工 | | S5 | bevy_asset 资产管线(真实纹理 + 字体) | ✅ 构建/体积/mock 回归 + 浏览器基线渲染验证通过;模拟器验证因工具链环境回归挂起(§9.5,与本项目无关,含复验指引) |

实测数据(S5)

| 项 | 数值 | |---|---| | wasm 原始(release, lto=thin, strip) | 30.07 MB | | wasm-opt -O4 后 | 30.07 MB(28.68 MiB) | | brotli -q11(.wasm.br,分包实际交付物) | 4.52 MB | | glue js(no-modules, patched) | 122 KB | | adapter.js | 49 KB | | assets(128x128 PNG + OFL ttf 字体) | 118.8 KB | | 主包(game.js + adapter.js + glue + 配置) | 174 KB(上限 4 MB)✓ | | bevy 分包(.wasm.br + assets) | 4.98 MB(主+分包合计 5.15 MB,上限 30 MB)✓ |

体积说明:S5 加了真实纹理 + 字体加载,wasm 只涨 6.3 KB(br 后)——bevy 的 2d 特性链本就内含 bevy_asset/bevy_text/png(见 devtools-verification.md §9.1),增量只有实际用到的加载/渲染路径。

构建与测试

mise install                    # 装 mise.toml 钉住的 node / wasm-bindgen-cli / binaryen(wasm-opt)
mise run build                  # 构建并组装 minigame/ 与 web/
mise run test                   # 微信环境 Node mock(boot 链 + 触摸探针)
mise run serve                  # 浏览器基线(本机即可验证真实渲染)

# 不经 mise 的等价命令(工具自备,版本要求同下):
# node tools/build.mjs / node tools/test-node-mock.mjs / node tools/serve.mjs

依赖口径与工具链分工(mise):mise.toml 钉 node ≥18、 wasm-bindgen-cli 0.2.129、wasm-opt(binaryen 130);rust 仍交给 rustup—— rust-toolchain.toml 钉 stable + wasm32-unknown-unknown target(target/component 管理是 rustup 的活,mise 官方亦建议;也避免与本机 scoop rustup 重复装整套工具链)。 python3 选配,仅重新生成演示纹理用。

tools/build.mjs(纯 Node 内置模块,零 npm 依赖):cargo 构建(RUSTFLAGS=-C target-feature=-reference-types)→ wasm-bindgen --target no-modules → wasm-opt → patch glue(path-only 守卫 + module.exports 导出,失配显式报错)→ brotli → 组装主包 + bevy/ 分包。 管线本体在 tools/lib/minigame-build.mjs,本文件只是 demo 的构建配置。

作为 npm 包使用(下游游戏)

kit 按可直接发布的 npm 包组织;下游游戏把工具链当依赖消费,不复制任何模板代码:

npm install @graviton-game/bevy-minigame-kit   # npm 包;开发期可用 file:../bevy-minigame-kit 链接本地
# .npmrc 写 install-links=false → 符号链接安装,kit 改动即时生效
// tools/build.mjs —— 下游的全部构建配置(完整示例见 bevy-minigame-example)
import { buildMinigame } from "@graviton-game/bevy-minigame-kit/build";
buildMinigame({
  root: new URL("..", import.meta.url).pathname,
  crateName: "my_game",
  projectName: "my-game",
  extraRootScripts: ["adapter/audio-bridge.js"], // 额外主包 JS(可选)
  extraBinAliasExts: [".wav"],                   // 追加 FSM 敏感扩展(可选)
});

| 子路径 | 用途 | |---|---| | @graviton-game/bevy-minigame-kit/build | buildMinigame(opts):cargo→bindgen→glue patch→wasm-opt→brotli→组装主包+数据分包+web 基线,含体积限额守卫 | | @graviton-game/bevy-minigame-kit/wx-mock | createWxMock 等:vm 沙箱微信环境(path-only WXWebAssembly、无 TextEncoder、wx API + InnerAudioContext 记录),CI 里验启动链 | | @graviton-game/bevy-minigame-kit/automator | findTarget/attachCdp/focusIde/canvasTapExpression + restart.mjs:开发者工具 CDP 验证驱动(上下文自动发现、失焦聚焦) |

适配器(adapter/minigame.js)由 buildMinigame 从包内自动取用,下游无需复制。

demo 内容

红/绿/蓝三个方块绕中心公转+自转,背景色缓慢渐变,黄色方块跟随最后一个指针 (触摸与鼠标双通道)。S5 起加入资产管线:AssetServer 经垫片 fetch 加载 真实 PNG 纹理(画面左上四象限纹理 sprite)+ OFL 像素字体(底部一行 ASSET OK 0123,bevy_text/parley 渲染),加载/失败均有 console 日志。 资产源在 assets/(build.mjs 拷入分包与 web 基线),纹理可用 python tools/make-texture.py 重新生成(纯标准库,无第三方依赖)。

微信开发者工具验证步骤(S2/S3,需 Mac/Windows)

  1. 安装微信开发者工具(Linux 可用社区移植版)
  2. 导入项目 → 目录选本仓库 minigame/ → AppID 选「测试号」 (已配 touristappid + compileType: game + bevy 分包)
  3. 编译,Console 预期输出:
[bevy-minigame-kit] 已安装微信 WebGL shader-link workaround(真机桥缺陷补丁)
[bevy-minigame-kit] canvas 375x667 @2 (backing 750x1334)
[boot] bevy-minigame-kit adapter s2 pathOnly: true
[S2] wasm 初始化完成,启动 Bevy…
...Creating new window bevy-minigame-kit...
[S2] Bevy 已启动(第一帧应在 canvas 上渲染)
INFO bevy heartbeat: t = 2.0s(每 2 秒一条,证明调度器活着)
  1. 画面:三色方块公转 + 背景渐变;模拟器里按住拖动,黄色方块应跟随手指
  2. 性能面板记录:运行内存(对比浏览器基线)——iOS 高性能模式上限 1~1.5GB, 官方建议关注 wasm 编译峰值(团结引擎文档:≈ wasm 文件大小 × 10)

真机验证 checklist(S4)

  • [ ] Android(微信 8.0.24+):扫码预览,确认第一帧 + 拖拽跟随 + 内存
  • [ ] iOS:公众平台开通「高性能模式」(能力地图→研发能力→生产提效包), game.json 加 "iOSHighPerformance": true,真机验证 WebGL2(iOS ≥ 15.5 建议)
  • [x] 长时间运行观察内存曲线(模拟器已验:10 分钟采样 JS 堆稳定 41.7–43.7 MB 无线性增长,单 setInterval 调度器泄漏 workaround 生效;真机待复核)
  • [x] wx.onShow/onHide 切后台/回前台:模拟器已验(最小化/恢复等价路径: 心跳归零→恢复、无崩溃);真机待复核
  • [ ] 弱网下分包加载失败的表现(game.js 已打错误日志)
  • [x] shader 编译/链接异常防护:模拟器已验 console 输出「已安装微信 WebGL shader-link workaround」(基础库 3.17.4)

模拟器验证详情与数据:docs/devtools-verification.md

已验证的技术要点(S1-S3 汇总)

  1. wasm 加载:无标准 WebAssembly 全局 → 别名 WXWebAssembly(path-only); glue 两处 patch 后按包内路径加载 .wasm.br(WXWebAssembly 原生解 brotli)
  2. instanceof 陷阱:Symbol.hasInstance 注册 Window/HTMLCanvasElement/ WebGL(2)RenderingContext 等类——web-sys/wgpu 的 dyn_into 全靠它(mock 验证 wgpu 确实走到了 surface 创建)
  3. 环境缺口:TextEncoder/TextDecoder 兜底、WXWebAssembly.Instance 空壳 (glue 的 instanceof 会因 undefined 抛 TypeError)、crypto.getRandomValues 兜底
  4. winit DOM 表面:document/canvas/style/getComputedStyle("Npx")/matchMedia/ ResizeObserver/IntersectionObserver/MessageChannel 全套垫片,浏览器基线证明 同一 wasm 在真浏览器也照常工作(patch 不破坏标准路径)
  5. 微信 GL 桥缺陷(自 bevy_gamekit 先例移植):shader-link 时序 workaround、 LINK_STATUS 布尔归一化、ASTC getSupportedProfiles 补齐
  6. rAF 泄漏:微信宿主对每次 rAF 注册保留簿记 → 常驻单 setInterval + JS 队列
  7. 渲染验证:浏览器基线(真 WebGL2)第一帧渲染 + 动画 + 指针跟随全部通过 (截图存证),同一 wasm 走微信 mock 链路推进到 wgpu surface 创建
  8. 资产管线(S5):bevy_asset wasm 端发 fetch("assets/…") 相对路径 + 精确 200/404 语义 + 缺省 meta 无害(源码级确认);垫片 fetch → FileSystemManager 加主包/分包候选回退;宿主 document 壳 currentScript=undefined 会让 wasm-bindgen glue 顶部崩溃(build.mjs patch 修复,详见 devtools-verification.md §9.3);浏览器基线纹理 + 字体渲染像素级验证通过(docs/screenshots/web-asset-pipeline.png)

工程结构

Cargo.toml            # Bevy 0.20 精简特性集(2d/touch/webgl2/bevy_log/std);
                      # bevy_asset/bevy_text/png 已内含于 2d 特性链,零额外特性
mise.toml             # mise 工具链钉版(node/wasm-bindgen-cli/binaryen)+ build/test/serve 任务
rust-toolchain.toml   # rustup 钉 stable + wasm32 target(rust 交给 rustup,mise 不重复管)
src/lib.rs            # demo:公转方块 + 指针跟随 + 心跳日志 + 纹理/字体资产加载;wasm 入口 start()
adapter/minigame.js   # ★ 适配层(~1100 行):环境垫片 + GL workaround + rAF 调度器
                      #   + fetch→FileSystemManager 垫片(主包/分包候选回退)
assets/               # 资产源(textures/ + fonts/),build.mjs 拷入分包与 web 基线
tools/build.mjs       # 一键构建 + glue patch + wasm-opt + brotli + 资产拷贝 + 组装(纯 node 内置模块)
tools/make-texture.py # 程序生成演示纹理(纯标准库 PNG 编码)
tools/test-node-mock.mjs  # 微信环境 Node mock(boot 链 + getContext 探针 + 触摸探针)
tools/serve.mjs          # 浏览器基线静态服务器(纯 node 内置模块,替代 python http.server)
tools/automator/      # 开发者工具 CDP 验证工具(listen/eval/soak/截图/像素分析/
                      #   分包上下文探针 contexts.js/crossctx.js 等)
minigame/             # 可导入微信开发者工具的工程(主包 + bevy/ 分包,build 产物 gitignore)
web/                  # 浏览器基线(同产物 + assets,验证 Rust 侧与 WebGL2 渲染)
docs/                 # 参考实现研究笔记 + 验证报告

后续路线(spike 之后)

  • 模拟器资产管线复验:待工具链环境恢复(重启机器)后按 devtools-verification.md §9.6 五分钟走完
  • 音频:wx.createInnerAudioContext / wx.createWebAudioContext 桥 + Bevy 自定义 audio plugin(bevy_audio 默认后端在小游戏不可用)
  • 体积压缩:feature 裁剪 → opt-level=z → 必要时 wasm-split 调用图分割
  • Rust 侧插件化:把 wx API(storage/lifecycle/systemInfo/setPreferredFPS)封装成 MinigamePlugin(参照 bevy_gamekit 的 bridge 模式)
  • iOS 高性能模式实机验证与内存预算