Un.mii
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.
// Type 22096: Adjustment // Type 22097: Assert // Type 22098: CharInfo // Type 22100: CharModel // Type 22105: CharModelImpl // Type 22106: CharModelInfo // Type 22107: Colors // Type 22108: CommonColorElement // Type 22109: ColorElement // Type 22110: FacelineColorElement // Type 22111: ColorIndexElement // Type 22112: ColorTable // Type 22113: Age // Type 22114: Gender // Type 22115: Race // Type 22116: FontRegion // Type 22117: FontRegionFlag // Type 22118: FavoriteColor // Type 22119: Expression // Type 22120: ExpressionFlag // Type 22121: GammaType // Type 22122: Nickname // Type 22123: Common // Type 22124: CoreDataEncoder // Type 22125: Database // Type 22126: DefaultMiiType // Type 22127: DefaultMii // Type 22128: CreateModelType // Type 22129: CreateNoseType // Type 22130: CreateFlag // Type 22131: ShapeQuality // Type 22132: TextureQuality // Type 22133: HeadPartsType // Type 22134: HeadPartsTransform // Type 22136: DrawParam // Type 22137: StoreDataLoadException // Type 22138: MeshLoadException // Type 22141: Faceline // Type 22142: FacelineTextureRenderer // Type 22144: FacelineTextureRendererBehaviour // Type 22145: Factory // Type 22146: HeadwearTransform // Type 22156: Mask // Type 22158: MaskTextureRenderer // Type 22160: MeshLoader // Type 22162: MeshResource // Type 22163: MiiController // Type 22164: RenderLog // Type 22168: MiiSkinShaderIds // Type 22169: ParamCharInfoAccessor // Type 22170: RegionMove // Type 22171: CommonColor // Type 22172: FacelineType // Type 22173: FacelineColor // Type 22174: FacelineWrinkle // Type 22175: FacelineMake // Type 22176: HairType // Type 22177: HairColor // Type 22178: HairFlip // Type 22179: EyeType // Type 22180: EyeColor // Type 22181: EyeScale // Type 22182: EyeAspect // Type 22183: EyeRotate // Type 22184: EyeX // Type 22185: EyeY // Type 22186: EyebrowType // Type 22187: EyebrowScale // Type 22188: EyebrowAspect // Type 22189: EyebrowRotate // Type 22190: EyebrowX // Type 22191: EyebrowY // Type 22192: NoseType // Type 22193: NoseScale // Type 22194: NoseY // Type 22195: MouthType // Type 22196: MouthScale // Type 22197: MouthAspect // Type 22198: MouthY // Type 22199: BeardType // Type 22200: MustacheType // Type 22201: MustacheScale // Type 22202: MustacheY // Type 22203: GlassType // Type 22204: GlassScale // Type 22205: GlassY // Type 22206: MoleType // Type 22207: MoleScale // Type 22208: MoleX // Type 22209: MoleY // Type 22210: VerifyReason // Type 22211: RandomMii // Type 22212: ResourceInfoData // Type 22213: Resource // Type 22214: TextureRenderer // Type 22215: TextureRendererState // Type 22217: TextureRendererBehaviour // Type 22218: Ver3MiiVersion // Type 22219: Ver3Copyable // Type 22220: Ver3NgWord // Type 22221: Ver3RoomIndex // Type 22222: Ver3PositionInRoom // Type 22223: Ver3AuthorType // Type 22224: Ver3BirthPlatform // Type 22225: Ver3BirthMonth // Type 22226: Ver3BirthDay // Type 22227: Ver3Favorite // Type 22228: Ver3MiiHeight // Type 22229: Ver3MiiBuild // Type 22230: Ver3LocalOnly // Type 22231: Ver3FacelineColor // Type 22232: Ver3HairColor // Type 22233: Ver3EyeColor // Type 22234: Ver3MouthColor // Type 22235: Ver3GlassColor // Type 22236: Ver3GlassType // Type 22237: Ver3StoreDataMember // Type 22238: Ver3StoreDataMemberType // Type 22239: Ver3StoreDataTableElement // Type 22240: Ver3Common // Type 22241: Ver3StoreDataRaw -- Anonymous namespace -- // Type 22099: DrawType // Type 22101: DrawTypeImpl // Type 22102: TextureTypeImpl // Type 22103: <>c__DisplayClass4_0 // Type 22104: <>c__DisplayClass4_1 // Type 22135: ModulateType // Type 22139: DrawType // Type 22140: TextureType // Type 22143: <Start>d__0 // Type 22147: DrawType // Type 22148: TextureType // Type 22149: EyePlaceParam // Type 22150: MouthExpression // Type 22151: OriginPosition // Type 22152: EyeComponent // Type 22153: ExpressionDrawParam // Type 22154: MaskPartsDesc // Type 22155: EyeTexturePair // Type 22157: <StartRendererAsync>d__4 // Type 22159: StreamType // Type 22161: ExtData // Type 22165: Int // Type 22166: Color // Type 22167: Texture

nn::mii resemblance
[edit | edit source]- 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
[edit | edit source]
- 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
[edit | edit source]- Pikmin Bloom
- While the global-metadata.dat is visible, it's not clear where all il2cpp types and methods go to.
- The Il2CppInspector tool is unable to open its libil2cpp.so.
- Mario Kart Tour(?)
- Its global-metadata.dat is hidden, and libil2cpp.so is reportedly encrypted: https://gameguardian.net/forum/topic/26082-mario-kart-tour/page/38/#comment-110128
- Mii assets also can't be found in its data.unity3d file, though these could also be obfuscated.