Skip to content

WeChat MiniGame

Estella exports the same project to WeChat MiniGames. You build the engine for the WeChat target, export the game from the editor, and open the result in WeChat DevTools.

The WeChat target compiles the C++ core with WeChat’s WXWebAssembly shims:

Terminal window
node build-tools/cli.js build -t wechat
# side modules, only if your game uses them:
node build-tools/cli.js build -t physics-wechat # physics
node build-tools/cli.js build -t spine-wechat # Spine (builds 2.1 + 3.8 + 4.1 + 4.2 + 4.3)
node build-tools/cli.js build -t dragonbones-wechat # DragonBones
node build-tools/cli.js build -t basis-wechat # KTX2 / compressed textures
node build-tools/cli.js build -t videodec-wechat # video (MPEG-1 wasm decoder)
  1. In Project Settings → Packaging → WeChat, set your AppID. Screen orientation is project-wide — set it once in Project Settings → Display → Orientation (it drives the game.json deviceOrientation below).

  2. Open File → Build…, pick the WeChat platform in the Package Project dialog, review the Scenes in build list, and click Package. Estella cooks assets, bundles the SDK + your scripts (as CommonJS, via esbuild), transforms scenes, and writes a standalone MiniGame package.

  3. Open the output folder in WeChat DevTools to compile, test, and submit. If you left the AppID empty, fill it in project.config.json from DevTools.

The output directory contains game.js (the entry, which boots game-bundle.js — the SDK + your scripts), game.json / project.config.json (WeChat config), the asset-manifest.json, your scenes as scenes/<name>.json, and a wasm/ folder holding the engine plus exactly the side modules your scenes need. Every scene in the build is a SceneManager.switchTo target — non-startup scenes load on their first switch (see Scenes).

Enable Compress textures in the Package dialog to cook PNGs to KTX2 — a smaller package and faster first load. Two WeChat-specific details, both handled automatically:

  • The Basis transcoder ships as the basis-wechat side module — build it once (above), or the export fails with the exact command to run.
  • WeChat’s code package only accepts whitelisted file suffixes, and ktx2 isn’t one — so the exporter stages every .ktx2 as .ktx2.bin, and the runtime resolves both spellings. The exporter also emits packOptions.include rules in project.config.json for every staged custom extension (.skel, .atlas, .bin, …) so DevTools packs and serves them.

The engine’s .wasm is the largest single file a mini-game ships. Two options on the WeChat page of Package Project keep it out of the 4 MB main package:

  • Compress wasm binaries ships the engine and every side module as .wasm.br, roughly a third of the size; WeChat decompresses them on load. This needs base library 2.14.0 or later. The package carries only the compressed file and nothing checks the version at run time, so set the minimum base library of your mini-game in the WeChat console to 2.14.0 when you turn this on.
  • Engine in a subpackage moves the binary into a 分包 that loads at startup. It no longer counts against the main package; startup waits for that download, with the loading bar showing its progress.

WeChat’s EmscriptenGLX runs the engine’s GL calls inside the wasm and hands them to the host in batches, instead of crossing into JavaScript for each one. In a scene of about a thousand draw calls it cut render time by about 12% on an Android phone.

Turn on Render through EmscriptenGLX on the WeChat page of Package Project, and build the engine it needs once:

Terminal window
node build-tools/cli.js build -t wechat-glx

The build downloads WeChat’s library at a pinned version and checks its hash, and uses emsdk 4.0.10 (installed into tools/emsdk-glx the first time) — the version that library is published for. It adds about 310 KB of wasm.

It takes effect on Android with base library 3.8.12 or later, and on iOS in 高性能+ mode. Any other host, including DevTools, renders through WebGL2 as before; the log’s rendering through … line says which one a device used.

Lazy asset groups become WeChat subPackages in game.json. At runtime, assets.loadGroup('level2') triggers wx.loadSubpackage under the hood, so levels download on demand rather than bloating the initial package:

{
"deviceOrientation": "landscape",
"subPackages": [
{ "name": "level2", "root": "subpackages/level2" }
]
}
  • Stay under the 4 MB main-package limit by moving on-demand content into subpackages/<name>/ — see Assets. The export sets bigPackageSizeSupport, so an oversized package still previews in DevTools — but upload enforces the cap.
  • Compress textures — see above; the single biggest package-size win.
  • Test in WeChat DevTools, not just the browser — the file system, storage, and socket backends differ from the web.
  • Preload the next level’s group (loadGroup) during play so the subpackage download doesn’t stall the transition.
  • Assets — addressable groups and cooking map onto subpackages.
  • Building & Exporting — the Package Project dialog.
  • Video — the MPEG-1 wasm decode path shipped for WeChat.
  • Networking — sockets use wx.connectSocket here.