Cross-Platform
Platform Strategy
Section titled “Platform Strategy”Every target is built from the same jengine-core crate:
| Target | Runtime | Rendering | Audio | Scripting |
|---|---|---|---|---|
| Windows | jengine-runtime (winit + wgpu) | DX12 / Vulkan | kira (cpal) | Luau (mlua) + JavaScript (rquickjs) |
| Android | jengine-runtime as a NativeActivity APK | Vulkan, GLES fallback | kira | Luau only |
| Web | jengine-web (wasm-bindgen) | WebGPU, WebGL2 fallback | Web Audio API | Fengari (Lua 5.3) |
| Editor | jengine-editor-viewport inside Tauri | WebGPU in WebView2 | Web Audio API | Fengari — the same bundle as web builds |
So what you verify in the editor is what a web build runs, while native runs Luau. Keep scripts to the common subset of the two Lua dialects, standard library included.
A project with its own Rust packages gets a generated crate per target —
<project>/.jengine/runtime/, /web/ and /viewport/ — that links them in.
Feature Gating
Section titled “Feature Gating”Platform-specific code uses cfg attributes (#[cfg(target_arch = "wasm32")],
#[cfg(target_os = "android")]) and Cargo features. jengine-core’s features:
| Feature | Brings |
|---|---|
native (default) | mlua (Luau) |
physics (default) | rapier2d |
audio (default) | kira |
js-adapter-host | rquickjs, for JavaScript and batch scripts on the desktop |
web | wasm-bindgen, web-sys, js-sys |
gpu-wgpu | the wgpu renderer |
backend-dx12, backend-vulkan, backend-metal, backend-webgpu, backend-webgl | one wgpu backend each |
cargo check -p jengine-core without gpu-wgpu does not compile the renderer; check renderer
changes with --features gpu-wgpu, or against the editor’s real target with
cargo check -p jengine-editor-viewport --target wasm32-unknown-unknown. Android-only code is checked
with cargo ndk -t arm64-v8a check -p jengine-runtime.
Shaders
Section titled “Shaders”Shaders are WGSL, one source for every backend. They live in
crates/jengine-core/assets/shaders/wgsl/ and are embedded at compile time with include_str!();
wgpu translates them to whatever the chosen backend speaks. Shader graphs generate WGSL too.
Avoid WGSL’s bit functions (firstTrailingBit and kin) in a shader the lights or sprites use: naga
writes them as GLSL ES 3.10 calls that WebGL2 cannot compile.
Which backends a build carries is a project setting (Project Settings → Graphics). A crate that
enables jengine-core/gpu-wgpu must name at least one backend feature or it compiles with no backend and
fails at adapter request at runtime.
Key Gotchas
Section titled “Key Gotchas”imagecrate: must usedefault-features = falseon WASM (rayon breaks single-threaded WASM)- WebGPU canvases offer no sRGB format: the browser hosts draw through an sRGB view of the canvas, so colours match native
winit0.30: windows are created inside the event loop (theResumedhandler), not beforeglamSIMD: enabled on WASM via.cargo/config.tomlwith-C target-feature=+simd128- Batch scripts run on the native desktop runtime only
- A web page served over
httpscannot open a plainws://socket to the online relay