Jump to content

Un.mii

From Mii Technical Wiki
Revision as of 17:00, 31 August 2025 by 172.28.0.1 (talk) (initial page: what is it, interesting facts, and why they made, why it is the way it is)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

un.mii is a Mii rendering and parsing library written in C# that was found to be used in Pikmin Bloom. Presumably, it's also used in Mario Kart Tour, given that it's also using Unity and can render 3D Mii heads.

Info about this library and its namespace hierarchy was found in Pikmin Bloom's global-metadata.dat, which stores metadata about .NET assemblies that were compiled using il2cpp, which is an obfuscation/optimization technique Unity uses when compiling .NET bytecode to native machine code.

In order to read the global-metadata.dat file, a tool such as this can be used: https://twy.name/Tools/global-metadata/. The un.mii namespace is included in Assembly-CSharp-firstpass.dll, although there are two others with one class each: CoreDataConverter.dll, CharInfoConverter.dll.

The library itself highly resembles nn::mii. Class names/members, enums, method names, and method parameters are all shared with nn::mii.

nn::mii resemblance

  • There are "CharModel" and "CharModelImpl" classes, which follow the "p_Impl" pattern that isn't typical in C#.
  • There are class members that are prefixed with "m", and argument names prefixed with "p" (pointer). Neither conventions are used in C#. (Look at "Mask")
  • Since C# is strictly object-oriented, all methods are now in classes. An example is the "Adjustment" class, taken from "mii_Adjustment.cpp". Names like "un.mii.Adjustment.GetEyeRotateOffset()" would've previously been "nn::mii::detail::GetEyeRotateOffset()", as C++ does not force everything to be in classes.
  • un.mii has many enums for every type, e.g.: EyeType, HairType, EyeScale, Ver3BirthPlatform, etc. These enums are also present in nn::mii, but there they're usually isolated to the "mii_ParamCommon.h" or "detail/mii_Ver3Common.h" headers, whereas here they all live in the un.mii namespace.
    • The enums are usually just made up of "Min", "Max", "End", sometimes "Empty", and on occasion other values.
  • The anonymous namespace of Assembly-CSharp-firstpass.dll contains types from un.mii that are also anonymous in nn::mii. For example: Three "DrawType" enums for faceline/mask/model, DrawTypeImpl also found in nn::mii::detail::CharModelImpl, then types seen in MaskImpl like ExpressionDrawParam, EyeComponent, EyePlaceParam, EyeTexturePair...
  • Some classes are "accessors" for data used with Get/Set methods, which are copied from nn::mii (e.g.: Ver3StoreDataRaw, ParamCharInfoAccessor), which are kept the same despite C# having property getter/setters that can be used instead. However, the CharInfo class does use properties with getters/setters.
  • There are also structs/enums from libnn_mii_core that had previously unknown fields. For example: Ver3StoreDataMember/Type, Ver3StoreDataTableElement, CommonColorElement, real names for Mask constants, VerifyReason, Ver3BirthPlatform max being 7, RandomMii tables... This makes it a good resource to reverse nn::mii.

Given all of this information, un.mii seems to be a direct source port of nn::mii in C# for use with Unity. There are many signs that the C++ code was directly ported without following C#/.NET conventions. There are also, of course, signs that it's only meant to be used with Unity.

Unique traits of the library

  • un.mii does not read any existing Mii resource file formats, instead opting to store and retrieve shape and texture data from the data.unity3d file, where you can indeed find shapes and textures for Miis in Pikmin Bloom's data.unity3d. The assets are also in the "un.mii" namespace.
    • Shapes are categorized as "middle" and "high", as well as having "low" and "middle" textures, once again suggesting the NintendoSDK/nn::mii lineage. The files are named with their internal part names (for example, "FaceT_line06") and may match up with internal tooling Nintendo uses to pack/unpack Mii resources.
    • Textures are stored in ASTC6x6, and stretched to the proper shape (e.g. eyes are stored in square shape)
  • There are "TextureRendererBehaviour" and "FacelineTextureRendererBehaviour" types, suggesting Mono behaviours. There's also Renderer classes for both, containing a "CreateGameObject" method that clearly refers to the Unity GameObject type. Likewise, CharModel and CharModelImpl have references to the RenderQueue type.
  • The "Database" class from nn::mii is kept, albehit just has three methods: GetDefault, GetRandom, and GetRandomVer3StoreData. So it has nothing to do with the Mii Database, but functions are categorized there just like nn::mii did.


Overall, it's just a port of the nn::mii codebase to C# with a few tweaks made for Unity. It's interesting given that nn::mii can be considered a port of FFL, with many pieces of code copy-pasted from it.

Ironically, given that Unity compiles .NET code to C++ anyway, it may have made more sense to just use nn::mii as-is using P/Invoke, like FFLSharp. However, the reasons they couldn't include that all versions of the Face Library heavily depend on the system/SDK's graphics API (GX, GX2, nn::gfx) and rely on their respective resource binary format. Interop with C libraries is also inconvenient and avoided in most languages, so combined with the inflexibility mentioned, is why they made the choice they did.

Notably for Miitomo they did go the route of modifying FFL to remove GX2 calls and made AFL, but it accumulated tech debt over time by trying to merge it with libnn_mii_core. It's less likely they would've done this for nn::mii, given that the way it manually manages graphics buffers and pipelines makes it even more dependent on nn::gfx than FFL is on GX2.

Uses