# Ayagami loads MOC3 models in Rust, and stops short of a stable API

> A Rust workspace of three crates that reads Live2D format MOC3 files, computes deformed ArtMeshes for a pose, and draws them through wgpu. The rendering work is specific and careful; the API wrapped around it is explicitly unstable and undocumented.

**AyagamiDev/ayagami** — 2D puppet model renderer compatible with Live2D

- Repository: https://github.com/AyagamiDev/ayagami
- Stars: 342 · Forks: 17
- Language: Rust
- License: Apache-2.0
- Published: 2026-09-18 · Updated: 2026-09-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/ayagamidev-ayagami

## Supported features stop at SDK 5.0 while the checklist claims 5.3

The model loader handles MOC3 files with features up to SDK 5.0: Parts, ArtMeshes, Rotation and Warp deformers, Glue, and Blendshape Parameters, with the list ending in an etc rather than an exhaustive enumeration. The roadmap checklist elsewhere has SDK 5.3 features marked done, and names them as advanced blend and offscreen rendering. Nothing in the two lists lines up cleanly, so the feature bullet is the safer bound to plan against and the 5.3 line is worth asking about directly rather than assuming. What is unambiguous is the layer the work sits at: reading a packed MOC3 file, computing deformed geometry for a pose, and drawing it. Everything adjacent to that layer is still unchecked, including expression file support, pose files with part linking, motion files, and full model file verification at load time.

## The driver turns a pose into deformed ArtMeshes

`ayagami::driver` is the crate that produces geometry. It builds on the core traits to compute model positions and deformations for a given pose, in the plainest terms available: a model plus parameters go in, deformed ArtMeshes come out. Those ArtMeshes are the draw objects a renderer consumes, which is why a renderer built on top never has to understand parameters at all. The algorithms that produce model behaviour live here rather than in the loader, including the subtle ones, namely deformer interpolation and extrapolation. That placement matters if you extend the library: a new deform type belongs in the driver, not in the file reader. The core traits underneath describe the puppet model rig only, deliberately excluding textures and auxiliary data, and they are what let the rest of the codebase stay generic over the model format.

## ayagami::file keeps the on-disk layout and admits it is obtuse

The packed MOC3 loader is described without much affection. It uses a batch of macros to generate accessors for file objects and properties automatically, while preserving the struct-of-arrays data organization that the on-disk file uses, driven by a high level description of the file objects held in `ayagami::file::classes`. Because the API is largely machine generated, it is called out as fairly obtuse and not documented. It remains usable if what you want is the raw data model of an MOC3 file. Between that generated layer and the rest of the library sits `ayagami::file::model`, which bridges the raw data and the higher level traits, offering a cleaner abstraction over model data and dropping implementation specific fields that the original implementation appears to have been built around, which the project says are not useful or safe to rely on.

## Partial recomputation, invisible skipping and 1:1 masks shape render cost

`ayagami-render` is a reference renderer built on wgpu-rs, with Vulkan, Metal, DirectX, OpenGL and WebGL/WebGPU backends, intended to be high quality, cross platform and efficient for desktop and VTubing use cases. Cost control shows up in three named behaviours. When parameters change, only the changed model portions and their masks are recomputed rather than the whole model. Items that are invisible are skipped instead of drawn. And masks are computed at 1:1 pixel quality, so clipping precision does not depend on an upscaled buffer. The integration story is deliberately narrow: this implementation suits engines that can run arbitrary GPU rendering code inside their own render loop, or that can have the model drawn into an offscreen texture. Engines needing custom shaders, extra texture layers such as emissive or normal maps, or control between layers are expected to do that work themselves. One caveat on scope: the architecture section of the project README stops mid sentence, partway through that list of advanced renderer needs, so nothing past offscreen textures is spelled out there.

The native demo is a two step affair:

```bash
cd ayagami-demo
cargo run -r
```

For the local web build, trunk serve --release is the documented substitute.

## Premultiplied alpha and a linear or sRGB choice set by the surface

Colour handling gets two explicit mentions. The renderer supports linear and sRGB, or gamma space, blending modes, and which one applies is selectable depending on the colour attachment configuration, so it is a property of the surface handed to the renderer rather than a global switch. On top of that it does premultiplied alpha and correct texture sampling, with the stated goal of avoiding the edge artifacts attributed to VTube Studio. Texture loading is described as multithreaded decoding plus GPU optimised colour conversion, which targets model load time rather than frame time. The demo app, built on egui for both web and native, is currently limited to sRGB blending because of egui limitations, with the intention of moving to linear light later. That gap is worth knowing before you compare a demo screenshot against one from an engine using linear blending, because the two are not promised to match.

## A pure Rust core that panics on inconsistent models

The safety argument is specific rather than general. The library is written in 100% pure Rust apart from a tiny code path in the optimized vertex buffer blending code, which is described as trivially provable to be sound. The consequence drawn from that is a hard one: an invalid model cannot cause undefined behavior or lead to an exploitable vulnerability, other than denial of service. What it can do is crash. Model validation is currently limited, so an inconsistent model, or a bug in the library, may cause a panic at runtime. The stated plan is to reject inconsistent models proactively and gracefully at load time instead, and that item sits unchecked next to the other verification work. In practice, the demo poser is currently the way to find out whether a given model loads cleanly, rather than any guarantee that a file you point at will render.

## The safe-only feature is a plan, not a build flag you can flip

Speed work is planned around deliberately scoped unsafe code, and the examples given are bounds check eliminations on object field array accesses in cases where the object index is already known to be in bounds. The stated design goal is zero undefined behavior regardless of input, with any unsafe code wrapped in safe abstractions, and the expectation that it introduces no vulnerabilities. The escape hatch for that work is a `safe-only` feature: users who want certainty can compile the unsafe paths out and trade performance for absolute memory safety. Both the unsafe work and the `safe-only` feature are unchecked items, so neither is something to plan a dependency on today. That matters most for anyone embedding the renderer in a long-lived desktop application, where a panic on a user supplied model is a bigger deal than it is in a throwaway command line tool.

## Two checked boxes worth noticing in an otherwise empty list

Of the roadmap items, the ones marked done are a screenshot tool in the demo poser app, a physics engine, a Godot component shipped as a separate repository at github.com/AyagamiDev/ayagami-gd, and the SDK 5.3 line already covered. Still open are documenting the MOC3 file format, expression file support, pose files with part linking, motion files for animation, full model file verification, a C compatible API, an embeddable web component, GPU compute acceleration for mesh deform, position tracking helpers for object pinning, conservative bounding box calculation, optimized clipping masks, and optimization work tied to the safe-only feature. The project's own status statement is equally plain: the API is pretty unstable and subject to change, there is no documentation yet, and a crates.io release is planned. The stated route to learning the API is to read `ayagami-demo` as the usage example, and the code is described as messy and released early to collect feedback on the API. Two licenses ship, LICENSE-MIT and LICENSE-APACHE, matching the dual MIT and Apache2 licensing that lets you pick either with no royalties or permission, including for expandable applications that load user provided models. There are no GitHub releases yet, and the last push to main is dated 14 September 2026.

## Conclusion

Choose Ayagami if you need to read MOC3 files and drive deformations from Rust, or want a wgpu renderer that recomputes only changed portions, skips invisible items and handles premultiplied alpha without the edge artifacts attributed to VTube Studio. Do not choose it as a dependency you can pin today: the API is described as unstable and subject to change, there is no documentation yet, no crates.io release and no GitHub releases, and model validation is limited enough that an inconsistent file can panic at runtime. If you need expression files, pose files, motion files, a C compatible API or an embeddable web component, none of those are built. Before committing, read `ayagami-demo`, since that is the stated usage example, and budget for the cleanup the author already promises.

## FAQ

### What is AyagamiDev/ayagami and what language is it written in?

Ayagami is a 2D puppet model loading and rendering library written in Rust, designed to be compatible with models in the Live2D model format while staying extensible to new formats. The Cargo workspace declares three members: ayagami, ayagami-demo and ayagami-render, resolved with resolver version 3.

### Which MOC3 features does Ayagami support?

MOC3 file loading is described as covering features up to SDK 5.0, including Parts, ArtMeshes, Rotation and Warp deformers, Glue, and Blendshape Parameters. Separately, the roadmap checklist marks SDK 5.3 advanced blend and offscreen rendering as finished.

### Is it safe to load an untrusted model file with Ayagami?

The core is 100% pure Rust apart from one tiny path in optimized vertex buffer blending that is described as trivially sound, so an invalid model cannot cause undefined behavior or an exploitable vulnerability beyond denial of service. Validation is still limited, so an inconsistent model or a bug in the library may panic at runtime.

### How do I run the Ayagami demo?

The web demo runs entirely in the browser and does not send your model data anywhere outside your machine. To run it as a native app, use cargo run -r inside the ayagami-demo directory; use trunk serve --release instead for the local web build.

### What license is Ayagami released under?

Ayagami is dual licensed under MIT and Apache2, so you may use it under whichever you choose without paying royalties or obtaining permission, including games with built-in models and expandable applications that load user provided models. Both LICENSE-MIT and LICENSE-APACHE ship in the repository root.

## Sources

- [AyagamiDev/ayagami on GitHub](https://github.com/AyagamiDev/ayagami)
- [Issues](https://github.com/AyagamiDev/ayagami/issues)
- [License: Apache-2.0](https://github.com/AyagamiDev/ayagami/blob/main/LICENSE)
- [README](https://github.com/AyagamiDev/ayagami/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ayagamidev-ayagami
