miijs 2.3.3 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,375 +1,363 @@
1
- # MiiJS
2
- MiiJS is a complete and comprehensive Mii library for reading, converting, modifying, writing, and rendering Mii characters from an accessible coding language. Support for all Mii types, including DS, Wii, 3DS, Wii U, Amiibo, Switch 1 & 2, Amiibos, and Mii Studio. Capable of making Special Miis and 3DS QR codes. Able to generate instructions to recreate Miis from scratch.
3
- <hr>
4
-
5
- ## Installation
6
- `npm install miijs` || `npm i miijs`
7
-
8
- <hr>
9
-
10
- ## Table of Contents
11
- - [Functions](#functions)
12
- - [Code Examples](#code-examples)
13
- - [Special Miis](#special-miis)
14
- - [Other Console Support](#other-console-support)
15
- - [`convertMii` Discrepancies](#discrepancies-in-convertmii-function)
16
- - [Transferring to/from the System](#transferring-miis-to-and-from-the-system)
17
- - [FFLResHigh.dat](#fflreshighdat)
18
- - [Credits](#credits)
19
-
20
- <hr>
21
-
22
- # Functions
23
-
24
- ### Reading Miis
25
- - **`async read3DSQR(PathToMiiQR OR BinaryDataFromQR, ReturnDecryptedBin?)`** - Returns JSON by default. By specifying `true` as the secondary parameter you can receive only the decrypted Mii data from the QR.
26
- - **`readWiiBin(PathToMii OR BinaryMiiData)`** - Returns JSON from a Wii Mii binary file.
27
-
28
- ### Writing Miis
29
- - **`async write3DSQR(MiiJSON, PathToWriteTo, fflRes?)`** - Writes a JPG QR of a 3DS scannable Mii to the path specified. If no fflRes is specified, the QR will render using Nintendo Studio's API. If one is provided, it will contain a locally rendered version. fflRes must either be passed as a buffer, or FFLResHigh.dat present in your project's root directory.
30
- - **`async writeWiiBin(MiiJSON, PathToWriteTo?)`** - Returns Mii binary which can then be written by default. If PathToWriteTo is specified, it will instead be written to a file.
31
-
32
- ### Converting Miis
33
- - **`convertMii(miiJson, typeTo?)`** - Converts the Mii JSON format between consoles (3DS ↔ Wii) and returns the JSON. If typeTo is not specified, converts to the opposite type.
34
- - **`convertMiiToStudio(miiJSON)`** - Returns a Studio compatible Mii in hex format.
35
- - **`convertStudioToMii(input)`** - Converts Studio format (hex string or Uint8Array) to 3DS Mii JSON.
36
-
37
- ### Rendering Miis
38
- - **`async renderMiiWithStudio(miiJSON)`** - Returns a buffer containing a PNG representation of the Mii's face using Nintendo's Studio API.
39
- - **`async renderMii(miiJSON, fflRes?)`** - Returns a buffer containing a PNG representation of the Mii's face using local rendering. fflRes must either be passed as a buffer, or FFLResHigh.dat present in your project's root directory. Currently bodies render but are unaffected by height and weight changes, though this is planned to be changed in the future.
40
-
41
- ### Amiibo Functions
42
- - **`insertMiiIntoAmiibo(amiiboDump, miiData)`** - Inserts Mii data (92 or 96 bytes, decrypted 3DS format) into an Amiibo dump. Returns the modified Amiibo dump.
43
- - **`extractMiiFromAmiibo(amiiboDump)`** - Extracts the Mii data (92 bytes, decrypted 3DS format) from an Amiibo dump. Returns a Buffer.
44
-
45
- ### Utility Functions
46
- - **`generateInstructions(miiJson, fullInstructions?)`** - Returns a JSON object of different instruction fields for manually recreating the Mii. If fullInstructions is not set, only the instructions that differ from a default Mii will be returned.
47
- - **`miiHeightToFeetInches(value)`** - Converts Mii height value (0-127) to real-world feet and inches. Returns `{feet, inches, totalInches}`.
48
- - **`inchesToMiiHeight(totalInches)`** - Converts real-world height in inches to Mii height value (0-127).
49
- - **`heightWeightToMiiWeight(heightInches, weightLbs)`** - Converts real-world height and weight to Mii weight value (0-127). **EXPERIMENTAL**
50
- - **`miiWeightToRealWeight(heightInches, miiWeight)`** - Converts Mii weight value to real-world pounds and BMI. Returns `{pounds, bmi}`. **EXPERIMENTAL**
51
-
52
- <hr>
53
-
54
- # Code Examples
55
-
56
- ## Reading a 3DS Mii from QR Code
57
- ```javascript
58
- const miijs = require('miijs');
59
-
60
- // Read from file path
61
- const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
62
- console.log('Mii Name:', miiJson.meta.name);
63
- console.log('Favorite Color:', miiJson.general.favoriteColor);
64
-
65
- // Or get just the decrypted binary data
66
- const decryptedBin = await miijs.read3DSQR('./example3DSQR.jpg', true);
67
- console.log('Decrypted binary length:', decryptedBin.length);
68
- ```
69
-
70
- ## Reading a Wii Mii from Binary File
71
- ```javascript
72
- const miijs = require('miijs');
73
-
74
- // Read from file path
75
- const miiJson = await miijs.readWiiBin('./exampleWii.bin');
76
- console.log('Mii Name:', miiJson.meta.name);
77
- console.log('Gender:', miiJson.general.gender === 0 ? 'Male' : 'Female');
78
-
79
- // Or pass binary data directly
80
- const fs = require('fs');
81
- const binaryData = fs.readFileSync('./exampleWii.bin');
82
- const miiJson2 = await miijs.readWiiBin(binaryData);
83
- ```
84
-
85
- ## Writing a 3DS Mii QR Code
86
- ```javascript
87
- const miijs = require('miijs');
88
-
89
- // First, read or create a Mii JSON
90
- const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
91
-
92
- // Write QR code with Studio rendering (no FFLResHigh.dat needed)
93
- await miijs.write3DSQR(miiJson, './output_qr.jpg');
94
-
95
- // Or with local rendering (requires FFLResHigh.dat in project root or passed as buffer)
96
- const fs = require('fs');
97
- const fflRes = fs.readFileSync('./FFLResHigh.dat');
98
- await miijs.write3DSQR(miiJson, './output_qr_local.jpg', fflRes);
99
- ```
100
-
101
- ## Writing a Wii Mii Binary
102
- ```javascript
103
- const miijs = require('miijs');
104
- const fs = require('fs');
105
-
106
- // Read a Mii (from any format)
107
- const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
108
-
109
- // Convert to Wii format first if needed
110
- const wiiMii = miijs.convertMii(miiJson, 'wii');
111
-
112
- // Write to file
113
- await miijs.writeWiiBin(wiiMii, './output_wii.bin');
114
-
115
- // Or get buffer without writing
116
- const buffer = await miijs.writeWiiBin(wiiMii);
117
- fs.writeFileSync('./manual_write.bin', buffer);
118
- ```
119
-
120
- ## Converting Between Formats
121
- ```javascript
122
- const miijs = require('miijs');
123
-
124
- // Read a 3DS Mii
125
- const ds3Mii = await miijs.read3DSQR('./example3DSQR.jpg');
126
-
127
- // Convert to Wii format
128
- const wiiMii = miijs.convertMii(ds3Mii, 'wii');
129
-
130
- // Convert back to 3DS
131
- const backTo3DS = miijs.convertMii(wiiMii, '3ds');
132
-
133
- // Auto-detect and convert to opposite
134
- const autoConverted = miijs.convertMii(ds3Mii);
135
- ```
136
-
137
- ## Converting to/from Studio Format
138
- ```javascript
139
- const miijs = require('miijs');
140
-
141
- // Read a Mii and convert to Studio format
142
- const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
143
- const studioHex = miijs.convertMiiToStudio(miiJson);
144
- console.log('Studio URL:', `https://studio.mii.nintendo.com/miis/image.png?data=${studioHex}`);
145
-
146
- // Convert Studio format back to JSON
147
- const studioData = '000d142a303f434b717a7b84939ba6b2bbbec5cbc9d0e2ea...';
148
- const miiFromStudio = miijs.convertStudioToMii(studioData);
149
- console.log('Converted Mii:', miiFromStudio.meta.name);
150
- ```
151
-
152
- ## Rendering Miis
153
- ```javascript
154
- const miijs = require('miijs');
155
- const fs = require('fs');
156
-
157
- // Read a Mii
158
- const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
159
-
160
- // Render using Studio API (simple, no setup needed)
161
- const studioPng = await miijs.renderMiiWithStudio(miiJson);
162
- fs.writeFileSync('./mii_studio_render.png', studioPng);
163
-
164
- // Render locally with full body (requires FFLResHigh.dat)
165
- const fflRes = fs.readFileSync('./FFLResHigh.dat');
166
- const localPng = await miijs.renderMii(miiJson, fflRes);
167
- fs.writeFileSync('./mii_local_render.png', localPng);
168
-
169
- // Shirt color comes from miiJson.general.favoriteColor
170
- ```
171
-
172
- ## Working with Amiibos
173
- ```javascript
174
- const miijs = require('miijs');
175
- const fs = require('fs');
176
-
177
- // Read an Amiibo dump
178
- const amiiboDump = fs.readFileSync('./exampleAmiiboDump.bin');
179
-
180
- // Extract the Mii from the Amiibo (returns 92 bytes decrypted)
181
- const miiData = miijs.extractMiiFromAmiibo(amiiboDump);
182
-
183
- // Convert the raw Mii data to readable JSON
184
- // (miiData is already decrypted 3DS format)
185
- const miiJson = miijs.decode3DSMii(miiData); // Note: decode3DSMii not exported, use read3DSQR workflow
186
-
187
- // Better workflow: Read from QR, get decrypted data, insert into Amiibo
188
- const qrMiiJson = await miijs.read3DSQR('./example3DSQR.jpg');
189
- const decryptedMiiData = await miijs.read3DSQR('./example3DSQR.jpg', true);
190
-
191
- // Insert new Mii into Amiibo
192
- const modifiedAmiibo = miijs.insertMiiIntoAmiibo(amiiboDump, decryptedMiiData);
193
- fs.writeFileSync('./modified_amiibo.bin', modifiedAmiibo);
194
- ```
195
-
196
- ## Generating Recreation Instructions
197
- ```javascript
198
- const miijs = require('miijs');
199
-
200
- // Read a Mii
201
- const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
202
-
203
- // Generate only non-default instructions (minimal)
204
- const minimalInstructions = miijs.generateInstructions(miiJson);
205
- console.log('Steps to recreate:');
206
- Object.values(minimalInstructions).forEach(step => {
207
- if (step) console.log('- ' + step);
208
- });
209
-
210
- // Generate complete instructions (every step)
211
- const fullInstructions = miijs.generateInstructions(miiJson, true);
212
- console.log('\nComplete recreation guide:');
213
- Object.entries(fullInstructions).forEach(([field, instruction]) => {
214
- console.log(`${field}: ${instruction}`);
215
- });
216
- ```
217
-
218
- ## Height and Weight Conversions
219
- ```javascript
220
- const miijs = require('miijs');
221
-
222
- // Convert Mii height (0-127) to feet/inches
223
- const heightInfo = miijs.miiHeightToFeetInches(64); // midpoint value
224
- console.log(`Height: ${heightInfo.feet}'${heightInfo.inches}" (${heightInfo.totalInches} inches)`);
225
-
226
- // Convert real height to Mii value
227
- const miiHeightValue = miijs.inchesToMiiHeight(72); // 6'0"
228
- console.log('Mii height value for 6\'0":', miiHeightValue);
229
-
230
- // EXPERIMENTAL: Convert real weight to Mii weight
231
- const heightInches = 69; // 5'9"
232
- const weightLbs = 160;
233
- const miiWeightValue = miijs.heightWeightToMiiWeight(heightInches, weightLbs);
234
- console.log('Mii weight value:', miiWeightValue);
235
-
236
- // EXPERIMENTAL: Convert Mii weight to real weight
237
- const weightInfo = miijs.miiWeightToRealWeight(heightInches, 64);
238
- console.log(`Weight: ${weightInfo.pounds.toFixed(1)} lbs, BMI: ${weightInfo.bmi.toFixed(1)}`);
239
- ```
240
-
241
- ## Creating and Modifying a Mii
242
- ```javascript
243
- const miijs = require('miijs');
244
-
245
- // Read an existing Mii
246
- const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
247
-
248
- // Modify properties
249
- miiJson.meta.name = 'Custom Name';
250
- miiJson.general.favoriteColor = 5; // Blue
251
- miiJson.hair.color = 0; // Black
252
- miiJson.eyes.color = 2; // Brown
253
-
254
- // Make it a Special Mii (3DS only)
255
- miiJson.meta.type = 'Special';
256
-
257
- // Convert to Wii format
258
- const wiiVersion = miijs.convertMii(miiJson, 'wii');
259
-
260
- // Save as both formats
261
- await miijs.write3DSQR(miiJson, './modified_3ds.jpg');
262
- await miijs.writeWiiBin(wiiVersion, './modified_wii.bin');
263
- ```
264
-
265
- ## Complete Workflow Example
266
- ```javascript
267
- const miijs = require('miijs');
268
- const fs = require('fs');
269
-
270
- async function processMyMii() {
271
- // 1. Read from QR code
272
- const mii = await miijs.read3DSQR('./example3DSQR.jpg');
273
- console.log('Loaded:', mii.meta.name);
274
-
275
- // 2. Customize the Mii
276
- mii.general.favoriteColor = 0; // Red
277
- mii.general.height = miijs.inchesToMiiHeight(66); // 5'6"
278
-
279
- // 3. Render it
280
- const renderBuffer = await miijs.renderMiiWithStudio(mii);
281
- fs.writeFileSync('./my_mii_face.png', renderBuffer);
282
-
283
- // 4. Generate recreation instructions
284
- const instructions = miijs.generateInstructions(mii);
285
- console.log('\nRecreation steps:', instructions);
286
-
287
- // 5. Export to multiple formats
288
- await miijs.write3DSQR(mii, './my_mii_qr.jpg');
289
-
290
- const wiiMii = miijs.convertMii(mii, 'wii');
291
- await miijs.writeWiiBin(wiiMii, './my_mii_wii.bin');
292
-
293
- const studioCode = miijs.convertMiiToStudio(mii);
294
- console.log('\nStudio URL:', `https://studio.mii.nintendo.com/miis/image.png?data=${studioCode}`);
295
-
296
- console.log('\nDone! All formats exported.');
297
- }
298
-
299
- processMyMii().catch(console.error);
300
- ```
301
-
302
- <hr>
303
-
304
- ## Special Miis
305
- Special Miis were on the Wii and 3DS, identifiable via their golden pants. They were created by Nintendo employees, and not consumers. They could not be edited, or copied. In every other instance transferring a Mii to another system would leave a copy on both systems. For Special Miis, they would delete themselves from the console sending them, and only ever be present in one place at a time per copy Nintendo sent out. When receiving them via QR code on the 3DS, it would only allow you to scan that QR once, and never again. On the Wii, these were distributed via the WiiConnect24 service, and would arrive via the Message Board. On the 3DS, these were distributed occasionally via Spotpass, Streetpass, and QR codes.
306
- ### Making a Special Mii
307
- To make a special Mii, read in the file using the appropriate function, set `mii.info.type="Special";`, and then write a new file with the appropriate function.
308
- -# Special Miis only work on the Wii and 3DS, and no other console.
309
-
310
- <hr>
311
-
312
- ## Other Console Support
313
- - DS
314
- - DS and Wii Miis are interchangeable. The DS only contains Miis in a handful of games, and is not baked into the system, however every instance where it does it is based off the Wii version of Miis, and to my current knowledge always provides a way to transfer from the Wii, being the only way short of recreation to transfer onto the DS. There is, to my knowledge, no way to transfer Miis off of the DS short of recreation.
315
- - Use Wii functions for DS Miis
316
- - Wii U
317
- - The Wii U and 3DS Miis are interchangeable, with one major exception. The 3DS has Special Miis, while the Wii U will not render any Mii set as a Special Mii. So since the 3DS has this one added feature, 3DS is what takes priority in the naming schemes across this project, however it is for all intents and purposes interchangeable with a Wii U Mii.
318
- - Use 3DS functions for Wii U Miis
319
- - Switch/2
320
- - Miis are more isolated than they've ever been on the Switch/2. To take them on and off of the Switch/2 via direct transfer, an Amiibo _and_ one of, a 3DS with NFC Reader accessory, New 3DS, or Wii U, is **required**. The only other method is to recreate manually from scratch. When the Switch writes to an Amiibo, it converts it to a 3DS/Wii U format. Due to this limitation of direct transfer, all Miis that this library can affect will be going through the 3DS/Wii U anyway, and direct Switch/2 support is thus irrelevant. The only differences between Switch Miis and Wii U Miis (no Special Mii support on the Switch either) is a ton more hair colors anyway.
321
- - Use 3DS, Studio, and Amiibo functions for Switch/2 Miis
322
- - Studio
323
- - Studio Miis are in essence Switch/2 Miis. Transferring directly on/off of Studio (a browser Mii Maker used purely for profile pictures across Nintendo's online logins) requires a developer console and code paste, or browser extension. I may undertake making my own version of this in the future, but for the time being [this tool](https://mii.tools/studioloader/) by HEYimHeroic serves this purpose (from what I can tell, I have not used it myself).
324
- - Use Studio Functions for Studio Miis
325
- - Miitomo/Kaerutomo and Tomodachi Life
326
- - Both Mii formats are the same as 3DS formats, with extra info added to the end. The way the library is set up, it can already read these. My devices are too new for Kaerutomo support, but I believe it should be able to scan the 3DS format Miis. Writing specific to Tomodachi Life Miis with game data already present in the QR is more within the realm of a Tomodachi Life save editor. I may undertake this for the Miis in the future, but it would be a separate project.
327
- - Use 3DS functions for these Miis
328
-
329
- <hr>
330
-
331
- ## Discrepancies in `convertMii` function
332
- All of these discrepancies __only__ apply when converting from the **3DS to the Wii**, converting from the Wii to the 3DS should be a perfect conversion.
333
- There is a reason that the Wii supports sending Miis to the 3DS, but not vice versa. Many of the fields on the 3DS are new, and not present on the Wii. This function does its absolute best to backport 3DS Miis, but it *is not perfect and never will be*. If you rely heavily on 3DS exclusive options in your Mii, the outputted Mii will likely not be satisfactory.
334
- - The 3DS has four more face shapes, thus some are converted to the closest possible for the Wii.
335
- - The 3DS allows you to set Makeup and Wrinkles seperately, as well as having 7 more "makeup" (including beard shadow and freckles) types and 5 more wrinkle types. This is probably one of the messiest conversions since one field has to be ignored entirely if both are set. Since the 3DS has some that are not even close to anything the Wii has, it will ignore these if the other field is set, allowing for the other field to be added in its place, prioritizing wrinkles over makeup. The outputted Mii will almost certainly require further editing to be satisfactory if these fields are used.
336
- - The 3DS has 6 extra nose types, all on the second page - these are mapped to similar noses on the first page that the Wii has.
337
- - The 3DS has an extra page of mouth types containing 12 extra mouth types. These are mapped to similar mouths on the other two pages that the Wii supports.
338
- - The 3DS has two extra lip colors. These are changed into the default Orangey lip color if used since both of the extra colors are closest to this.
339
- - The Wii does not have the option to "squish" parts to be thinner. This function ignores this field as a result.
340
- - The 3DS has 60 extra hairstyles. These are mapped to hairstyles the Wii does have. This will not be a perfect conversion and has a decent chance of needing a manual change.
341
- - The 3DS has an extra page of eye types that the Wii does not, which the function maps to a similar eye type that the Wii does support if used. Will likely require a manual edit.
342
- - The 3DS has two extra mustaches and two extra beards. These are mapped to a similar beard or mustache if used - the two extra beards will likely need a manual change if used.
343
-
344
- <hr>
345
-
346
- # Transferring Miis to and from the System
347
- - DS
348
- - If the game you would like to transfer Miis to supports it, the option to "Connect to Wii" will be found in various places and worded different ways. The main game you might want to do this for is Tomodachi Collection, which will be in Town Hall after three Mii residents are on the island. On the Wii, you then want to press the DS icon in the top right and follow the prompts from there. If the option is not present, press and _release_ **A**, press and release **B**, press and release **1**, and then press and _hold_ **2**. The option should then be visible. This option is not available on Wii U or the Wii mode of the Wii U, and can only be used to send Miis to DS and 3DS, not from. No option to retrieve Miis from the DS is available besides recreating the Mii.
349
- - Wii
350
- - Method 1 (Recommended, doesn't require homebrew): Connect the Wiimote to your PC, Dolphin seems to be the easiest way to do so though there are some more difficult ways to do so, and use [WDMLMiiTransfer](https://sourceforge.net/projects/wdml/files/WDML%20-%20MiiTransfer/). Open the `readSlotX.bat` file for the slot you're trying to read from (Array notation, 0=1, 1=2, 2=3, and so on). The Mii will be in the same directory under the name `miiX.mii`, where X is the same number as the readSlot you opened. If you used `readSlotAll.bat`, then there will be 10 Miis (0-9) in the directory. Note that if no Mii was ever present in that slot ever on the Wiimote, it will still output a `miiX.mii` file, though it will not contain the Mii data correctly. To write to the Wiimote, make sure the Mii you're writing is in the same directory and named `miiX.mii`, where X is the slot you're writing to, and open `writeSlotX.bat`, where X is the slot you're writing to (in array notation). You can transfer Miis on and off the Wiimote from the Wii by using the Wiimote icon in the top right of Mii Maker.
351
- - Method 2 (Requires Homebrew, is untested by me): [Mii Installer](https://wiibrew.org/wiki/Mii_Installer) for writing from the SD card to the Wii, and [Mii Extractor](https://wiibrew.org/wiki/Mii_Extractor) for reading from the Wii.
352
- - 3DS and Wii U
353
- - Open Mii Maker, select "QR Code/Image Options", and then select the respective QR Code option, be it scanning a QR code or saving a Mii as a QR code.
354
- - Amiibo
355
- - You can use [Tagmo](https://play.google.com/store/apps/details?id=com.hiddenramblings.tagmo.eightbit&hl=en_US&pli=1) on Android, bottom right NFC button -> Backup to retrieve an Amiibo file, or Amiibo bin in explorer -> Write: first write to blank NTAG215 tag OR Update: subsequent writes to already-an-Amiibo tags. _Reportedly_ [one of these apps](https://www.reddit.com/r/tagmo/comments/ynxonu/list_of_ios_iphone_amiibo_apps/) can be used for an equivalent on iPhone. I have not tested and cannot verify any of the iPhone apps at this time.
356
- - Switch/2
357
- - You have to use Amiibos as a conduit to interact with Miis on the Switch/2. To take these Miis on and off of the Switch, in System Settings under the Amiibo menu you can register or change the Owner Mii to set the Mii stored on the Amiibo, and under Miis you can select Create a Mii and then Copy from Amiibo to take a Mii from the Amiibo onto the Switch.
358
-
359
- <sub>If you are unable to transfer to the console you wish to, you can use the `generateInstructions` function provided here and manually recreate the Mii on the console using the provided instructions.</sub>
360
-
361
- <hr>
362
-
363
- ## FFLResHigh.dat
364
- FFLResHigh.dat provides the necessary models and textures to build a 3D model of the Mii. This will not be provided by the library but can be provided by placing it in the directory of the project calling MiiJS. By providing FFLResHigh.dat, you can then render Miis locally without using Studio. If you do not have or do not provide FFLResHigh.dat, rendering is still available via Studio.
365
- ### Finding FFLResHigh.dat
366
- Any version of AFLResHigh.dat will work as well, renamed to FFLResHigh.dat.
367
- You can find FFLResHigh using a Wii U with an FTP program installed at `sys/title/0005001b/10056000/content/FFLResHigh.dat`. From a Miitomo install, it can be found in the cache at `res/asset/model/character/mii/AFLResHigh_2_3.dat`.
368
-
369
- <hr>
370
-
371
- # Credits
372
- - **[kazuki-4ys' MiiInfoEditorCTR](https://github.com/kazuki-4ys/kazuki-4ys.github.io/tree/master/web_apps/MiiInfoEditorCTR)** - I repurposed how to decrypt and reencrypt the QR codes from here, including repurposing the asmCrypto.js file in its entirety with very small modifications (it has since been stripped down to only include the functions this library uses). I believe I also modified the code for rendering the Mii using Nintendo's Mii Studio from here as well, though I do not remember for certain.
373
- - **[ariankordi's FFL.js](https://github.com/ariankordi/FFL.js/)** - Rendering Miis locally would not be possible without this library. Instructions for finding FFLResHigh are also learned from [ariankordi's FFL-Testing repository](https://github.com/ariankordi/FFL-Testing).
374
- - **[Models Resource](https://models.spriters-resource.com/3ds/systembios/asset/306260/)** - For the bodies used in Mii rendering
1
+ # MiiJS
2
+ MiiJS is a complete and comprehensive Mii library for reading, converting, modifying, writing, and rendering Mii characters from an accessible coding language. Support for all Mii types, including DS, Wii, 3DS, Wii U, Amiibo, Switch 1 & 2, Amiibos, and Mii Studio. Capable of making Special Miis and 3DS QR codes. Able to generate instructions to recreate Miis from scratch.
3
+ <hr>
4
+
5
+ ## Installation
6
+ `npm install miijs` || `npm i miijs`
7
+
8
+ <hr>
9
+
10
+ ## Table of Contents
11
+ - [Functions](#functions)
12
+ - [Code Examples](#code-examples)
13
+ - [Special Miis](#special-miis)
14
+ - [Other Console Support](#other-console-support)
15
+ - [`convertMii` Discrepancies](#discrepancies-in-convertmii-function)
16
+ - [Transferring to/from the System](#transferring-miis-to-and-from-the-system)
17
+ - [FFLResHigh.dat](#fflreshighdat)
18
+ - [Credits](#credits)
19
+
20
+ <hr>
21
+
22
+ # Functions
23
+
24
+ ### Reading Miis
25
+ - **`async read3DSQR(PathToMiiQR OR BinaryDataFromQR, ReturnDecryptedBin?)`** - Returns JSON by default. By specifying `true` as the secondary parameter you can receive only the decrypted Mii data from the QR.
26
+ - **`readWiiBin(PathToMii OR BinaryMiiData)`** - Returns JSON from a Wii Mii binary file.
27
+
28
+ ### Writing Miis
29
+ - **`async write3DSQR(MiiJSON, PathToWriteTo, fflRes?)`** - Writes a JPG QR of a 3DS scannable Mii to the path specified. If no fflRes is specified, the QR will render using Nintendo Studio's API. If one is provided, it will contain a locally rendered version. fflRes must either be passed as a buffer, or FFLResHigh.dat present in your project's root directory.
30
+ - **`async writeWiiBin(MiiJSON, PathToWriteTo?)`** - Returns Mii binary which can then be written by default. If PathToWriteTo is specified, it will instead be written to a file.
31
+
32
+ ### Converting Miis
33
+ - **`convertMii(miiJson, typeTo?)`** - Converts the Mii JSON format between consoles (3DS ↔ Wii) and returns the JSON. If typeTo is not specified, converts to the opposite type.
34
+ - **`convertMiiToStudio(miiJSON)`** - Returns a Studio compatible Mii in hex format.
35
+ - **`convertStudioToMii(input)`** - Converts Studio format (hex string or Uint8Array) to 3DS Mii JSON.
36
+
37
+ ### Rendering Miis
38
+ - **`async renderMiiWithStudio(miiJSON)`** - Returns a buffer containing a PNG representation of the Mii's face using Nintendo's Studio API.
39
+ - **`async renderMii(miiJSON, fflRes?)`** - Returns a buffer containing a PNG representation of the Mii's face using local rendering. fflRes must either be passed as a buffer, or FFLResHigh.dat present in your project's root directory. Currently bodies render but are unaffected by height and weight changes, though this is planned to be changed in the future.
40
+
41
+ ### Amiibo Functions
42
+ - **`insertMiiIntoAmiibo(amiiboDump, miiData)`** - Inserts Mii data (92 or 96 bytes, decrypted 3DS format) into an Amiibo dump. Returns the modified Amiibo dump.
43
+ - **`extractMiiFromAmiibo(amiiboDump)`** - Extracts the Mii data (92 bytes, decrypted 3DS format) from an Amiibo dump. Returns a Buffer.
44
+
45
+ ### Utility Functions
46
+ - **`generateInstructions(miiJson, fullInstructions?)`** - Returns a JSON object of different instruction fields for manually recreating the Mii. If fullInstructions is not set, only the instructions that differ from a default Mii will be returned.
47
+ - **`miiHeightToMeasurements(miiHeight)`** - Converts Mii height value (0-127) to real-world feet and inches. Returns `{feet, inches, totalInches, centimeters}`.
48
+ - **`inchesToMiiHeight(totalInches)`** - Converts real-world height in inches to Mii height value (0-127).
49
+ - **`centimetersToMiiHeight(totalCentimeters)`** - Converts real-world height in centimeters to Mii height value (0-127).
50
+ - **`miiWeightToRealWeight(miiWeight)`** - Converts Mii weight value (0-127) to real-world weight values. Returns `{pounds, kilograms}`.
51
+ - **`imperialHeightWeightToMiiWeight(heightInches, weightLbs)`** - Converts real-world imperial measurements to Mii weight values.
52
+ - **`metricHeightWeightToMiiWeight(heightCentimeters, weightKilograms)`** - Converts real-world metric measurements to Mii weight values.
53
+
54
+ ### Other Functions
55
+ - **`makeChild(miiJson1, miiJson2, options?)`** - Returns an array of 6 different Mii JSONs, which represent a child generated from the two parent Miis passed to the function at different stages of life. This is somewhat experimental, but should be accurate to my current knowledge. You can pass any or none of { name: "The Name", creatorName: "The Name", favoriteColor: 0-11, gender: 0-1/\*0:Male, 1:Female\*/ }
56
+
57
+ <hr>
58
+
59
+ # Code Examples
60
+
61
+ ## Reading a 3DS Mii from QR Code
62
+ ```javascript
63
+ const miijs = require('miijs');
64
+
65
+ // Read from file path
66
+ const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
67
+ console.log('Mii Name:', miiJson.meta.name);
68
+ console.log('Favorite Color:', miiJson.general.favoriteColor);
69
+
70
+ // Or get just the decrypted binary data
71
+ const decryptedBin = await miijs.read3DSQR('./example3DSQR.jpg', true);
72
+ console.log('Decrypted binary length:', decryptedBin.length);
73
+ ```
74
+
75
+ ## Reading a Wii Mii from Binary File
76
+ ```javascript
77
+ const miijs = require('miijs');
78
+
79
+ // Read from file path
80
+ const miiJson = await miijs.readWiiBin('./exampleWii.bin');
81
+ console.log('Mii Name:', miiJson.meta.name);
82
+ console.log('Gender:', miiJson.general.gender === 0 ? 'Male' : 'Female');
83
+
84
+ // Or pass binary data directly
85
+ const fs = require('fs');
86
+ const binaryData = fs.readFileSync('./exampleWii.bin');
87
+ const miiJson2 = await miijs.readWiiBin(binaryData);
88
+ ```
89
+
90
+ ## Writing a 3DS Mii QR Code
91
+ ```javascript
92
+ const miijs = require('miijs');
93
+
94
+ // First, read or create a Mii JSON
95
+ const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
96
+
97
+ // Write QR code with Studio rendering (no FFLResHigh.dat needed)
98
+ await miijs.write3DSQR(miiJson, './output_qr.jpg');
99
+
100
+ // Or with local rendering (requires FFLResHigh.dat in project root or passed as buffer)
101
+ const fs = require('fs');
102
+ const fflRes = fs.readFileSync('./FFLResHigh.dat');
103
+ await miijs.write3DSQR(miiJson, './output_qr_local.jpg', fflRes);
104
+ ```
105
+
106
+ ## Writing a Wii Mii Binary
107
+ ```javascript
108
+ const miijs = require('miijs');
109
+ const fs = require('fs');
110
+
111
+ // Read a Mii (from any format)
112
+ const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
113
+
114
+ // Convert to Wii format first if needed
115
+ const wiiMii = miijs.convertMii(miiJson, 'wii');
116
+
117
+ // Write to file
118
+ await miijs.writeWiiBin(wiiMii, './output_wii.bin');
119
+
120
+ // Or get buffer without writing
121
+ const buffer = await miijs.writeWiiBin(wiiMii);
122
+ fs.writeFileSync('./manual_write.bin', buffer);
123
+ ```
124
+
125
+ ## Converting Between Formats
126
+ ```javascript
127
+ const miijs = require('miijs');
128
+
129
+ // Read a 3DS Mii
130
+ const ds3Mii = await miijs.read3DSQR('./example3DSQR.jpg');
131
+
132
+ // Convert to Wii format
133
+ const wiiMii = miijs.convertMii(ds3Mii, 'wii');
134
+
135
+ // Convert back to 3DS
136
+ const backTo3DS = miijs.convertMii(wiiMii, '3ds');
137
+
138
+ // Auto-detect and convert to opposite
139
+ const autoConverted = miijs.convertMii(ds3Mii);
140
+ ```
141
+
142
+ ## Converting to/from Studio Format
143
+ ```javascript
144
+ const miijs = require('miijs');
145
+
146
+ // Read a Mii and convert to Studio format
147
+ const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
148
+ const studioHex = miijs.convertMiiToStudio(miiJson);
149
+ console.log('Studio URL:', `https://studio.mii.nintendo.com/miis/image.png?data=${studioHex}`);
150
+
151
+ // Convert Studio format back to JSON
152
+ const studioData = '000d142a303f434b717a7b84939ba6b2bbbec5cbc9d0e2ea...';
153
+ const miiFromStudio = miijs.convertStudioToMii(studioData);
154
+ console.log('Converted Mii:', miiFromStudio.meta.name);
155
+ ```
156
+
157
+ ## Rendering Miis
158
+ ```javascript
159
+ const miijs = require('miijs');
160
+ const fs = require('fs');
161
+
162
+ // Read a Mii
163
+ const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
164
+
165
+ // Render using Studio API (simple, no setup needed)
166
+ const studioPng = await miijs.renderMiiWithStudio(miiJson);
167
+ fs.writeFileSync('./mii_studio_render.png', studioPng);
168
+
169
+ // Render locally with full body (requires FFLResHigh.dat)
170
+ const fflRes = fs.readFileSync('./FFLResHigh.dat');
171
+ const localPng = await miijs.renderMii(miiJson, fflRes);
172
+ fs.writeFileSync('./mii_local_render.png', localPng);
173
+
174
+ // Shirt color comes from miiJson.general.favoriteColor
175
+ ```
176
+
177
+ ## Working with Amiibos
178
+ ```javascript
179
+ const miijs = require('miijs');
180
+ const fs = require('fs');
181
+
182
+ // Read an Amiibo dump
183
+ const amiiboDump = fs.readFileSync('./exampleAmiiboDump.bin');
184
+
185
+ // Extract the Mii from the Amiibo (returns 92 bytes decrypted)
186
+ const miiData = miijs.extractMiiFromAmiibo(amiiboDump);
187
+
188
+ // Convert the raw Mii data to readable JSON
189
+ // (miiData is already decrypted 3DS format)
190
+ const miiJson = miijs.decode3DSMii(miiData); // Note: decode3DSMii not exported, use read3DSQR workflow
191
+
192
+ // Better workflow: Read from QR, get decrypted data, insert into Amiibo
193
+ const qrMiiJson = await miijs.read3DSQR('./example3DSQR.jpg');
194
+ const decryptedMiiData = await miijs.read3DSQR('./example3DSQR.jpg', true);
195
+
196
+ // Insert new Mii into Amiibo
197
+ const modifiedAmiibo = miijs.insertMiiIntoAmiibo(amiiboDump, decryptedMiiData);
198
+ fs.writeFileSync('./modified_amiibo.bin', modifiedAmiibo);
199
+ ```
200
+
201
+ ## Generating Recreation Instructions
202
+ ```javascript
203
+ const miijs = require('miijs');
204
+
205
+ // Read a Mii
206
+ const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
207
+
208
+ // Generate only non-default instructions (minimal)
209
+ const minimalInstructions = miijs.generateInstructions(miiJson);
210
+ console.log('Steps to recreate:');
211
+ Object.values(minimalInstructions).forEach(step => {
212
+ if (step) console.log('- ' + step);
213
+ });
214
+
215
+ // Generate complete instructions (every step)
216
+ const fullInstructions = miijs.generateInstructions(miiJson, true);
217
+ console.log('\nComplete recreation guide:');
218
+ Object.entries(fullInstructions).forEach(([field, instruction]) => {
219
+ console.log(`${field}: ${instruction}`);
220
+ });
221
+ ```
222
+
223
+ ## Height and Weight Conversions
224
+ ```javascript
225
+ const miijs = require('miijs');
226
+
227
+ // Convert Mii height (0-127) to feet/inches
228
+ const heightInfo = miijs.miiHeightToFeetInches(64); // midpoint value
229
+ console.log(`Height: ${heightInfo.feet}'${heightInfo.inches}" (${heightInfo.totalInches} inches)`);
230
+
231
+ // Convert real height to Mii value
232
+ const miiHeightValue = miijs.inchesToMiiHeight(72); // 6'0"
233
+ console.log('Mii height value for 6\'0":', miiHeightValue);
234
+
235
+ // EXPERIMENTAL: Convert real weight to Mii weight
236
+ const heightInches = 69; // 5'9"
237
+ const weightLbs = 160;
238
+ const miiWeightValue = miijs.heightWeightToMiiWeight(heightInches, weightLbs);
239
+ console.log('Mii weight value:', miiWeightValue);
240
+
241
+ // EXPERIMENTAL: Convert Mii weight to real weight
242
+ const weightInfo = miijs.miiWeightToRealWeight(heightInches, 64);
243
+ console.log(`Weight: ${weightInfo.pounds.toFixed(1)} lbs, BMI: ${weightInfo.bmi.toFixed(1)}`);
244
+ ```
245
+
246
+ ## Creating and Modifying a Mii
247
+ ```javascript
248
+ const miijs = require('miijs');
249
+
250
+ // Read an existing Mii
251
+ const miiJson = await miijs.read3DSQR('./example3DSQR.jpg');
252
+
253
+ // Modify properties
254
+ miiJson.meta.name = 'Custom Name';
255
+ miiJson.general.favoriteColor = 5; // Blue
256
+ miiJson.hair.color = 0; // Black
257
+ miiJson.eyes.color = 2; // Brown
258
+
259
+ // Make it a Special Mii (3DS only)
260
+ miiJson.meta.type = 'Special';
261
+
262
+ // Convert to Wii format
263
+ const wiiVersion = miijs.convertMii(miiJson, 'wii');
264
+
265
+ // Save as both formats
266
+ await miijs.write3DSQR(miiJson, './modified_3ds.jpg');
267
+ await miijs.writeWiiBin(wiiVersion, './modified_wii.bin');
268
+ ```
269
+
270
+ ## Making a Child from Two Miis
271
+ ```javascript
272
+ const fs = require('fs');
273
+ const miijs = require('miijs');
274
+
275
+ //Read the parents
276
+ const dad = await miijs.read3DSQR('./dad.jpg');
277
+ const mom = await miijs.read3DSQR('./mom.jpg');
278
+
279
+ //Make the child
280
+ const child = miijs.makeChild(dad,mom);
281
+
282
+ //Write the child to a file, and then render all of the stages
283
+ fs.writeFileSync(`./${child[0].meta.name}.json`,JSON.stringify(child,null,4));
284
+ for(var i=0;i<child.length;i++){
285
+ let img=await miijs.renderMii(child[i]);
286
+ fs.writeFileSync(`./${child[i].meta.name}`,img);
287
+ }
288
+ ```
289
+
290
+ <hr>
291
+
292
+ ## Special Miis
293
+ Special Miis were on the Wii and 3DS, identifiable via their golden pants. They were created by Nintendo employees, and not consumers. They could not be edited, or copied. In every other instance transferring a Mii to another system would leave a copy on both systems. For Special Miis, they would delete themselves from the console sending them, and only ever be present in one place at a time per copy Nintendo sent out. When receiving them via QR code on the 3DS, it would only allow you to scan that QR once, and never again. On the Wii, these were distributed via the WiiConnect24 service, and would arrive via the Message Board. On the 3DS, these were distributed occasionally via Spotpass, Streetpass, and QR codes.
294
+ ### Making a Special Mii
295
+ To make a special Mii, read in the file using the appropriate function, set `mii.info.type="Special";`, and then write a new file with the appropriate function.
296
+ -# Special Miis only work on the Wii and 3DS, and no other console.
297
+
298
+ <hr>
299
+
300
+ ## Other Console Support
301
+ - DS
302
+ - DS and Wii Miis are interchangeable. The DS only contains Miis in a handful of games, and is not baked into the system, however every instance where it does it is based off the Wii version of Miis, and to my current knowledge always provides a way to transfer from the Wii, being the only way short of recreation to transfer onto the DS. There is, to my knowledge, no way to transfer Miis off of the DS short of recreation.
303
+ - Use Wii functions for DS Miis
304
+ - Wii U
305
+ - The Wii U and 3DS Miis are interchangeable, with one major exception. The 3DS has Special Miis, while the Wii U will not render any Mii set as a Special Mii. So since the 3DS has this one added feature, 3DS is what takes priority in the naming schemes across this project, however it is for all intents and purposes interchangeable with a Wii U Mii.
306
+ - Use 3DS functions for Wii U Miis
307
+ - Switch/2
308
+ - Miis are more isolated than they've ever been on the Switch/2. To take them on and off of the Switch/2 via direct transfer, an Amiibo _and_ one of, a 3DS with NFC Reader accessory, New 3DS, or Wii U, is **required**. The only other method is to recreate manually from scratch. When the Switch writes to an Amiibo, it converts it to a 3DS/Wii U format. Due to this limitation of direct transfer, all Miis that this library can affect will be going through the 3DS/Wii U anyway, and direct Switch/2 support is thus irrelevant. The only differences between Switch Miis and Wii U Miis (no Special Mii support on the Switch either) is a ton more hair colors anyway.
309
+ - Use 3DS, Studio, and Amiibo functions for Switch/2 Miis
310
+ - Studio
311
+ - Studio Miis are in essence Switch/2 Miis. Transferring directly on/off of Studio (a browser Mii Maker used purely for profile pictures across Nintendo's online logins) requires a developer console and code paste, or browser extension. I may undertake making my own version of this in the future, but for the time being [this tool](https://mii.tools/studioloader/) by HEYimHeroic serves this purpose (from what I can tell, I have not used it myself).
312
+ - Use Studio Functions for Studio Miis
313
+ - Miitomo/Kaerutomo and Tomodachi Life
314
+ - Both Mii formats are the same as 3DS formats, with extra info added to the end. The way the library is set up, it can already read these. My devices are too new for Kaerutomo support, but I believe it should be able to scan the 3DS format Miis. Writing specific to Tomodachi Life Miis with game data already present in the QR is more within the realm of a Tomodachi Life save editor. I may undertake this for the Miis in the future, but it would be a separate project.
315
+ - Use 3DS functions for these Miis
316
+
317
+ <hr>
318
+
319
+ ## Discrepancies in `convertMii` function
320
+ All of these discrepancies __only__ apply when converting from the **3DS to the Wii**, converting from the Wii to the 3DS should be a perfect conversion.
321
+ There is a reason that the Wii supports sending Miis to the 3DS, but not vice versa. Many of the fields on the 3DS are new, and not present on the Wii. This function does its absolute best to backport 3DS Miis, but it *is not perfect and never will be*. If you rely heavily on 3DS exclusive options in your Mii, the outputted Mii will likely not be satisfactory.
322
+ - The 3DS has four more face shapes, thus some are converted to the closest possible for the Wii.
323
+ - The 3DS allows you to set Makeup and Wrinkles seperately, as well as having 7 more "makeup" (including beard shadow and freckles) types and 5 more wrinkle types. This is probably one of the messiest conversions since one field has to be ignored entirely if both are set. Since the 3DS has some that are not even close to anything the Wii has, it will ignore these if the other field is set, allowing for the other field to be added in its place, prioritizing wrinkles over makeup. The outputted Mii will almost certainly require further editing to be satisfactory if these fields are used.
324
+ - The 3DS has 6 extra nose types, all on the second page - these are mapped to similar noses on the first page that the Wii has.
325
+ - The 3DS has an extra page of mouth types containing 12 extra mouth types. These are mapped to similar mouths on the other two pages that the Wii supports.
326
+ - The 3DS has two extra lip colors. These are changed into the default Orangey lip color if used since both of the extra colors are closest to this.
327
+ - The Wii does not have the option to "squish" parts to be thinner. This function ignores this field as a result.
328
+ - The 3DS has 60 extra hairstyles. These are mapped to hairstyles the Wii does have. This will not be a perfect conversion and has a decent chance of needing a manual change.
329
+ - The 3DS has an extra page of eye types that the Wii does not, which the function maps to a similar eye type that the Wii does support if used. Will likely require a manual edit.
330
+ - The 3DS has two extra mustaches and two extra beards. These are mapped to a similar beard or mustache if used - the two extra beards will likely need a manual change if used.
331
+
332
+ <hr>
333
+
334
+ # Transferring Miis to and from the System
335
+ - DS
336
+ - If the game you would like to transfer Miis to supports it, the option to "Connect to Wii" will be found in various places and worded different ways. The main game you might want to do this for is Tomodachi Collection, which will be in Town Hall after three Mii residents are on the island. On the Wii, you then want to press the DS icon in the top right and follow the prompts from there. If the option is not present, press and _release_ **A**, press and release **B**, press and release **1**, and then press and _hold_ **2**. The option should then be visible. This option is not available on Wii U or the Wii mode of the Wii U, and can only be used to send Miis to DS and 3DS, not from. No option to retrieve Miis from the DS is available besides recreating the Mii.
337
+ - Wii
338
+ - Method 1 (Recommended, doesn't require homebrew): Connect the Wiimote to your PC, Dolphin seems to be the easiest way to do so though there are some more difficult ways to do so, and use [WDMLMiiTransfer](https://sourceforge.net/projects/wdml/files/WDML%20-%20MiiTransfer/). Open the `readSlotX.bat` file for the slot you're trying to read from (Array notation, 0=1, 1=2, 2=3, and so on). The Mii will be in the same directory under the name `miiX.mii`, where X is the same number as the readSlot you opened. If you used `readSlotAll.bat`, then there will be 10 Miis (0-9) in the directory. Note that if no Mii was ever present in that slot ever on the Wiimote, it will still output a `miiX.mii` file, though it will not contain the Mii data correctly. To write to the Wiimote, make sure the Mii you're writing is in the same directory and named `miiX.mii`, where X is the slot you're writing to, and open `writeSlotX.bat`, where X is the slot you're writing to (in array notation). You can transfer Miis on and off the Wiimote from the Wii by using the Wiimote icon in the top right of Mii Maker.
339
+ - Method 2 (Requires Homebrew, is untested by me): [Mii Installer](https://wiibrew.org/wiki/Mii_Installer) for writing from the SD card to the Wii, and [Mii Extractor](https://wiibrew.org/wiki/Mii_Extractor) for reading from the Wii.
340
+ - 3DS and Wii U
341
+ - Open Mii Maker, select "QR Code/Image Options", and then select the respective QR Code option, be it scanning a QR code or saving a Mii as a QR code.
342
+ - Amiibo
343
+ - You can use [Tagmo](https://play.google.com/store/apps/details?id=com.hiddenramblings.tagmo.eightbit&hl=en_US&pli=1) on Android, bottom right NFC button -> Backup to retrieve an Amiibo file, or Amiibo bin in explorer -> Write: first write to blank NTAG215 tag OR Update: subsequent writes to already-an-Amiibo tags. _Reportedly_ [one of these apps](https://www.reddit.com/r/tagmo/comments/ynxonu/list_of_ios_iphone_amiibo_apps/) can be used for an equivalent on iPhone. I have not tested and cannot verify any of the iPhone apps at this time.
344
+ - Switch/2
345
+ - You have to use Amiibos as a conduit to interact with Miis on the Switch/2. To take these Miis on and off of the Switch, in System Settings under the Amiibo menu you can register or change the Owner Mii to set the Mii stored on the Amiibo, and under Miis you can select Create a Mii and then Copy from Amiibo to take a Mii from the Amiibo onto the Switch.
346
+
347
+ <sub>If you are unable to transfer to the console you wish to, you can use the `generateInstructions` function provided here and manually recreate the Mii on the console using the provided instructions.</sub>
348
+
349
+ <hr>
350
+
351
+ ## FFLResHigh.dat
352
+ FFLResHigh.dat provides the necessary models and textures to build a 3D model of the Mii. This will not be provided by the library but can be provided by placing it in the directory of the project calling MiiJS. By providing FFLResHigh.dat, you can then render Miis locally without using Studio. If you do not have or do not provide FFLResHigh.dat, rendering is still available via Studio.
353
+ ### Finding FFLResHigh.dat
354
+ Any version of AFLResHigh.dat will work as well, renamed to FFLResHigh.dat.
355
+ You can find FFLResHigh using a Wii U with an FTP program installed at `sys/title/0005001b/10056000/content/FFLResHigh.dat`. From a Miitomo install, it can be found in the cache at `res/asset/model/character/mii/AFLResHigh_2_3.dat`.
356
+
357
+ <hr>
358
+
359
+ # Credits
360
+ - **[kazuki-4ys' MiiInfoEditorCTR](https://github.com/kazuki-4ys/kazuki-4ys.github.io/tree/master/web_apps/MiiInfoEditorCTR)** - I repurposed how to decrypt and reencrypt the QR codes from here, including repurposing the asmCrypto.js file in its entirety with very small modifications (it has since been stripped down to only include the functions this library uses). I believe I also modified the code for rendering the Mii using Nintendo's Mii Studio from here as well, though I do not remember for certain.
361
+ - **[ariankordi's FFL.js](https://github.com/ariankordi/FFL.js/)** - Rendering Miis locally would not be possible without this library. Instructions for finding FFLResHigh are also learned from [ariankordi's FFL-Testing repository](https://github.com/ariankordi/FFL-Testing).
362
+ - **[Models Resource](https://models.spriters-resource.com/3ds/systembios/asset/306260/)** - For the bodies used in Mii rendering
375
363
  - **[socram8888's Amiitools](https://github.com/socram8888/amiitool)** - I _think_, for the code reverse engineered to help with aspects of Amiibo dump processing. I went through so many iterations in research and coding, there may be other credits due as well but I _think_ this was the only repo actually used for the reverse engineering in the final working code.