Systems
WMMD architecture: a hostable MMD runtime
Why the engine is split into layered Rust crates with hard dependency invariants, so the same code can drive an editor, an AR host, or an offline renderer.
WMMD is a hostable MikuMikuDance runtime and rendering backend written in Rust. “Hostable” is the whole design constraint: the same codebase drives a desktop editor today, and is meant to be embedded in VJ tools, AR and VR runtimes, game engines, mocap pipelines, and offline renderers. That only works if no layer secretly assumes it owns the window, the GPU, or the clock.
The layering
The workspace is a set of crates arranged so that dependencies point one way:
wmmd-clock— the transport clock, with zero external dependencies at all.wmmd-runtime— the CPU-only simulation engine: scene data, skeletons, physics backends, the IK solver, and the frame update loop.wmmd-asset— PMX/PMD parsing, VMD animation loading, texture analysis, and path resolution; it delegates material work towmmd-material.wmmd-render— the backend-agnostic render interface. It depends onglamandserdeand nothing else.wmmd-render-wgpu— the wgpu implementation of that interface, owning every GPU pass.wmmd-host-winit— a desktop surface, and only a surface.wmmd-session,wmmd-ui-egui,wmmd-audio,wmmd-export,wmmd-editor,wmmd-desktop,wmmd-tools— host-neutral session state, panels, audio, offline export, and the applications on top.
The invariants are the architecture
The dependency graph is enforced by a written list of invariants, and violating one is treated as a bug rather than a style question. The ones that shape everything else:
wmmd-renderhas zero GPU dependencies and zero runtime dependencies. GPU layout types likeCameraUniformlive in the wgpu crate; the abstract interface never references runtime commands.wmmd-runtimenever loads files. The host calls the asset crate and pushes anAddModelcommand carrying an already-parsed asset. The engine has no opinion about your filesystem.wmmd-render-wgpunever owns the swapchain. The host acquires the frame, builds a render target, callsrender(), and presents. That single rule is what lets an AR or headless host exist at all.wmmd-render-wgpuis egui-free, andwmmd-host-winitis surface-only — the GPU context lives in the render crate so a host without winit can still create a device.RenderRequestis the single interface point. Callers assemble camera, shadow center, lighting, debug flags, and frame, then hand it over.wmmd-clockandwmmd-audioare standalone. Neither knows anything about scenes or rendering; the host wires them to the runtime.
Why this discipline pays
Every one of those rules is a refusal to take a shortcut that would have been easier in a desktop-only engine. The payoff is that adding a new surface — a Vision Pro host, a VJ plugin, an export job — is a matter of driving the existing interfaces rather than forking the renderer. The engine is also model-agnostic by rule: fixes are made at the system level and never branch on a particular MMD model, so a bug reproduced with one file is fixed for the whole space of valid PMX and VMD inputs.