Wii U Downloadable Content from Start to Finish

This tutorial clearly describes the process of delivering add-on content (AOC) from initial development through packaging and shipping. It also describes the features of the AOC API. The AOC API deals only with one-off purchase items. Other types of content available for purchase, such as consumable AOC, are called service items and use a REST-oriented API. Handling service items using the REST API is outside the scope of this discussion.


Term Definition
add-on content Add-on content (AOC, also referred to as downloadable content, or DLC, in consumer-facing documentation) is purchased by users from the Nintendo eShop. After purchase, it can be used in applications. Instances of downloadable content are identified by an index starting from 1.
content item A content item is a unit of data that a user purchases from Nintendo eShop. It consists of a single directory in the content directory of a submission, and all of the files and subdirectories in that directory. The maximum size for a single content item is 4 GB. Content items can contain multiple files and/or actual in-game items. For example, one content item may add a new sword or a sword and shield.
item set An item set is another unit of purchase available on Nintendo eShop. An item set must contain at least one content item and no more than 64 content items. For example, a shield and a helmet may be individually purchasable content items, and an armor item set may contain both the shield and the helmet content items. Creating and managing item sets is performed entirely in IMAS. You do not need to duplicate content items that are included in multiple item sets.
catalog Groups of items or content are managed as catalogs. Catalogs are the units in which developers submit add-on content and service items to Nintendo, and the units in which they are eventually released to Nintendo eShop. When you create a new catalog, the status is set to Developing. Each data title and/or service title can be managed in multiple catalogs. You can also manage the associations between each catalog and the items and content. Normally, a catalog transitions through states on its way toward a release. The content and items in each catalog are independent. If you edit the content and items in one catalog, you do not affect any other catalogs.
data title A data title is one of the packages that is submitted to Lotcheck. It is a unique variation of one of the AOC unique IDs for the title. The data title is an archived ROM file that contains metadata content and the add-on content that users purchase. A data title may contain up to 255 content items and be up to 10 GB in size.
metadata content Metadata content stores the name of the add-on content, a description of the add-on content, an icon image, attributes such as the sale price and sale period, and other information. You may generate metadata using ctr_makeMetaDataContent, based on the content information (XML) that is exported from IMAS.
title_id A title_id is a 64-bit value, usually written in hexadecimal format, that is used for identification. For more information about the structure of a title ID, see Title ID and Unique ID Overview.
AOC unique ID AOC unique IDs are used to reference groups of data titles which may be accessed by an application. To provide an application access to all content items released with that AOC unique ID, enter the AOC unique ID into one of the add_on_unique_id# fields in the meta.xml file for the application. An AOC unique ID is a five-digit hexadecimal number that is provided by NOA Submissions and NOE Lotcheck. An AOC unique ID is part of the title ID for a data title. With the variation portion of the title ID, a AOC unique ID may have up to 256 data titles. For example, if the title ID for a data title is “0005000C154321FF,” the AOC Unique ID is “54321,” and the variation (the least significant byte) is “FF” (255).


To use AOC, write the code in the application that locates the AOC. The code consists of two parts: code that helps the user purchase the content through Nintendo eShop, and code that tells the game how to find and use the purchased AOC.

Jumping to eShop

To jump to the page in Nintendo eShop for your application, the user may press the HOME Button while the application is running, and then select the icon for eShop. With this method, there is no need to incorporate any special code into the application. Nintendo eShop starts and a page displays software details about the suspended application.

If you want to provide the user the option to jump from the game directly to the page in Nintendo eShop for your application, use the SYSSwitchToEShop function with a pointer to a SysEShopArgsIn structure. For more information on the SYSSwitchToEShop function, see the API Reference.

Using AOC In-Game

To use an AOC in a game, the required AOC must already be purchased and downloaded to the console. The AOC API functions only handle activities such as determining which data titles pertain to the current application and whether a content item has been purchased. Use FS API functions to access the purchased content, using the paths determined by the AOC API functions. To include the AOC API in a project, include nn/aoc.h and link the nn_aoc.a library.


Call AOC_Initialize before any other AOC function. It is not necessary to check the return value of this function, because it can only return successfully and may be safely called multiple times.

Many functions in the AOC library require a work buffer to be passed to them. You may allocate this buffer once, and then pass it to every function that requires it before deleting it. The size of the work buffer may be determined by using AOC_CalculateWorkBufferSize([in] maxTitles), which takes the maximum number of data titles that may be listed for the title. A safe maximum for this may be determined by the constant AOC_MAX_TITLES_NUM, which is equal to the maximum number of AOC unique IDs, each with the maximum number of variations, although for most applications a much smaller value is usually sufficient. It is important to remember that the working buffer must be 64-byte aligned.

Finding Purchased Content

Discovering available purchased content on the system is a five-step process. Each step of the process must complete before the next step starts (blocking), and should not be run from the main thread. All I/O interrupts from the CPU are performed on Core 2, and Core 2 is always available to the application, even when it is in the background. Since the functions involve file I/O, they should be called on Core 2 for the best performance with the least potential for pitfalls.

  1. List Available Data Titles

    On the Wii U, purchased content items cannot be listed directly. Only the data titles containing the purchased content items may be listed. The data title directory lists only downloaded content items, not all content items for the data title.

    To list data titles, use AOC_ListTitle([out] numTitles, [out] titleList, [in] maxTitles, [in] workBuffer, [in] workBufferSize). This function passes back the number of unique data titles in the first parameter and an array of titles of type AOC_TitleListType in the second. It is important to remember that the working buffer must be 64-byte aligned.

    Because the path field of the AOC_TitleListType structure is deprecated, the array of these structures gathered from AOC_ListTitle is useful only as a collection of handles to the other functions in the AOC library.

  2. Open a Data Title

    A data title must be opened before you may access its content items. Performing FS operations on a data title path returns errors if the title is not currently open. To open a title, use AOC_OpenTitle([out] path, [in] targetTitle, [in] workBuffer, [in] workBufferSize), which outputs the path for the title as the first parameter, using an AOC_TitleListType pointer obtained by AOC_ListTitle and a 64-byte aligned working buffer.

    The size of the character array where the path is returned is dictated by the constant AOC_MAX_CONTENT_PATH_SIZE. It is important to consider this is the maximum size of the path only up to the data title level. When transitioning deeper, such as to the actual content items, the maximum length of the path grows accordingly.

    The number of data titles that may be opened at a time is dictated by the constant AOC_MAX_OPENABLE_TITLE_NUM. This may be less than the number of data titles an application may access. To list content items, it is recommended that you first list the available data titles, in a loop open a single data title and open its content items, and then close the data title. Listing and opening all available data titles and then listing all content items available to the application is not recommended, because of the limits on the number of open titles.

  3. List Content Items

    There is no AOC function for listing content items. The FS library should be used for this purpose and for more in-depth AOC data access, such as opening files. Listing of content items should be performed with a simple directory scan performed on the path provided by AOC_OpenTitle. The directories within this path should all be four characters long, consisting of hexadecimal values starting at 0010. Each of these directories represents a downloaded content item.

    Because there is no method of obtaining further information about the AOC, it is recommend that you include some form of metadata within each content item directory which can be accessed in a consistent manner. In the end, however, the entire format and structure of a content item directory is left up to the developer.

  4. Determine Purchased Content

    The fact that a content item exists does not guarantee that it was purchased, or that the purchase is still valid. To ensure that the user has access rights to content items, check the content items using the AOC_GetPurchaseInfo([out] contentPurchased, [in] dataTitleId, [in] contentItems, [in] numContentItems, [in] workBuffer, [in] workBufferSize) function. The AOC_GetPurchaseInfo function outputs an array of 4-byte integer values (0 for not purchased, 1 for purchased), each corresponding to an entry in an array of u16 content items. In addition to these two arrays, you need to provide the function with a title ID of the data title, the number of indices in the array, the work buffer, and the size of that work buffer.

    The title ID of the data title is found in the titleId member of the AOC_TitleListType returned from the AOC_ListTitle function. The values in the array of content items may be determined by converting the content item directory names that were found in step 3 to integers from C strings containing hexadecimal digits. The ANSI-C function strtoul found in stdlib.h with base 16 works well for this purpose.

    Since AOC_GetPurchaseInfo works with lists of content items, the recommended program flow is to generate a list of all indices by scanning all content items, pass the entire list to the function, and then process the content items that were purchased. This sequence of actions yields better performance than testing the purchase status of individual content items.

  5. Close a Data Title

    Close a data title only after completing all FS operations on every content item in a data title. Attempting to close the data title while file operations are still ongoing, or attempting a file operation in a content item directory after its data title is closed, results in an error. To close the title, use the function AOC_CloseTitle ([in] dataTitle), which uses the AOC_TitleListType pointer that was returned by AOC_ListTitle.

Deleting Content

Occasionally, you may want to delete content items from the console, for example, when deleting content items one-by-one as recommended in the add-on content guidelines. To perform this action, use the AOC_DeleteContent([in] dataTitleId, [in] contentItems, [in] numContentItems, [in] workBuffer, [in] workBufferSize) function. Like AOC_GetPurchaseInfo, AOC_DeleteContent requires an array of content item indices. To determine these indices, use the ANSI-C function strtoul with a base of 16 on the content item directory names found within the root directory of the data title.

You cannot prevent a deleted content item from being downloaded again from Nintendo eShop. Deleting content items is not viable in the implementation of consumable AOC; this must be performed using the REST API.


After all work with the AOC library is finished, shut the library down with the function AOC_Finalize. No matter how many times AOC_Initialize is called, only one AOC_Finalize call is required. Since you are finished with the AOC work buffer, you ensure that you free it as well.

If any data titles are still open, AOC_Finalize fails and returns an error.

Error Handling

To report the failures and successes of AOC functions, the AOC library uses the AOCStatus type that is returned by each function in the library. Generally speaking, most of the error conditions are caused by programming errors that should be fixed during development. In the event that a bug causes an error in a production environment, use the Error/Eula Viewer to display general error messages.

Build and Install an AOC

When the code to load and use the AOC in the application is complete, the next step is to build the AOC and install it on a CAT-DEV to test. The process of building the AOC and installing it is relatively straightforward.

Preparing an Application

To Prepare an Application

  1. The application itself must include a method to announce which data titles it has permission to access. This is performed in groups of data titles with the same AOC unique ID. To add all data titles for an AOC unique ID to an application, the unique ID is placed in one of the add_on_unique_id# fields in the meta.xml file for the title.

    There are 32 add_on_unique_id# fields in the meta.xml file. Since each AOC unique ID enables a title to make 256 more submissions, each with as many content items as desired up to 255 or 10 GB. The purpose of the additional fields is primarily to allow titles to share AOCs between them.

  2. If you are not mastering with the Application Configuration Tool, also change the cos.xml file for your application. Locate the p5 tag under the permissions tag. In the p5 tag, there are two other tags, group and mask. The current content of the mask tag is 0000000000000011. Change it to 0000000000000091, which sets an AOC permission bit.
    If you do not complete this step, the application will not have the appropriate permission required to open data titles and AOC_OpenTitle returns the error AOC_STATUS_INTERNAL_ERROR.

Packaging AOC

The AOC directory structure determines which files are in what content item. The root directory of the AOC directory tree may contain only the folders code, content, and meta. Files in the code and meta directories should be generated by the Application Configuration Tool, which is covered in the Mastering a Submission section. For now, leave those directories empty. It is important to consider that the AOC unique ID is specified in the title_id for the data title, which is set in the app.xml file in the code folder. Since we are not working with the code folder at this time, the title_id is automatically set to 0005000C11000000 the first time that the AOC is used, making the AOC unique ID 0x10000 by default.

The content directory, may contain only directories with 4-digit hexadecimal names in sequences starting with 0010. Each directory name is a unique content item which may be made available for purchase on Nintendo eShop. For example, if you are preparing a package that has 200 content items, the folders are named 0010, 0011, 0012 . . ., 00D6, and 00D7. Each of the content item folders may contain as many files and subdirectories as necessary, in a format that is understood by the application code.

Installing the AOC

There are three methods for installing AOC on a devkit (CAT-DEV or CAT-R), each with various pros and cons. You may install the AOC on the devkit by:

To access installed AOC, the application must be installed. AOC_ListTitle does not list any SD card installed data titles if the application itself is not installed on the devkit or running from the disk.

Install to $CAFE_ROOT/data/mlc

Copying AOC directly to $CAFE_ROOT/data/mlc is the fastest method of getting AOC onto the devkit and accessible to your application. The disadvantage to this method is that the AOC is not marked as purchased. This means that while using this method, circumvent the code in your application that verifies the AOC purchase. This method is an ideal solution for rapid iteration on the add-on content, but does not provide the user experience for testing the AOC system that the SD card method does.

The application must be running from the host PC.

  1. On the host PC, navigate to $CAFE_ROOT/data/mlc/usr/title.
  2. Create a folder named 0005000c (the upper 4 bytes of any title_id for the data title), if one does not already exist.
  3. Copy your AOC root directory in $CAFE_ROOT/data/mlc/usr/title.
  4. Rename the AOC root directory, using the 1<AOC unique ID><variation> format. This corresponds to the lower 4-bytes of the title_id for the data title. For example, if your AOC unique ID is 0x23456 and you are on variation 01, rename the AOC root directory to 12345601. The final path for the AOC root directory is $CAFE_ROOT/data/mlc/usr/title/0005000c/12345601.

For your application to access the data titles that you copied to the AOC root directory, boot the CAT-DEV in PCFS mode and start the application from the host PC. If the application is not running from the host PC, AOC_ListTitle does not list any data titles that are installed in $CAFE_ROOT/data/mlc/usr/title/0005000c/<AOCRootDirectory>.

Install from an SD Card

If you want to properly test your AOC system, and you are not trying to rapidly iterate while testing the AOC itself, perform an SD card install. The following actions need only be carried out if installing the AOC via the SD card method. After the AOC has been laid out in the correct directory structure, an AOC wumad should be built via the following instructions:

  1. On the hostPC, navigate to the directory where you installed the SDK, and then double-click cafe.bat.
  2. At the command prompt, type cd $CAFE_ROOT/data/mlc/usr/title/0005000c/<AOCRootDirectory>.
  3. At the command prompt, type makecfmaster aoc <AOC_ROOT_DIRECTORY> <AOC_NAME>.
  4. At the command prompt, type cd $CAFE_ROOT/data/mlc/usr/title/0005000c/<AOCRootDirectory>/outdir.
  5. At the command prompt, type makecfdownloadimage.sh -i <AOC_NAME>.wumad -o ./. This packages the AOC in the $CAFE_ROOT/data/mlc/usr/title/0005000c/<AOCRootDirectory>/outdir directory that is named <AOC_NAME>_p01.
  6. Copy the installable directory <AOC_NAME>_p01 to the root of an SD card.
  7. On the CAT-DEV or CAT-R, insert the SD card, and then use the System Config Tool to install the AOC.

Install the AOC Tutorial

This section provides information and instructions to help you successfully install and run the AOCTutorial project on a CAT-DEV, including the AOC1 package and AOC2 package. It also helps clarify the configuration steps required when using non-default values, such as the AOC Unique ID, and when doing multiple submissions, as you would for a real project.

The following two formats are provided for reference:

1UUUUU is the five-digit hexadecimal AOC unique ID.
2VV is the two-digit hexadecimal variation.

Preconditions and Project Configuration

In this VSI project the nn_aoc.a library is linked to provide access to the AOC functions. By default, VSI does not link the nn_aoc.a library, making it necessary for you to add the library in your program.

The RPX for this project is output to the code directory, where the default app.xml and cos.xml files are located. A default cos.xml file is located in the meta directory.

The AOC1 and AOC2 directories are AOC root directories. Each root directory contains content, code, and meta directories. The app.xml and cos.xml files in the code directory, and the meta.xml file in the meta directory require some configuration changes. Do not make any changes to the files and folders in the content directory.

Configuring the XML Files for Your Application

Use the information in this section as a guide to help you configure the app.xml, cos.xml, and meta.xml files for your application. Sample versions of the XML files, with the suggested changes in the table, are provided to help you locate and change the items listed in the table. Working configuration files are included for your reference.

File Description of Changes to Make
  • title_id: Select a five-digit hexadecimal value for the unique ID. The value must be between 0x10000 and 0xF7000. Do not change the two-digit hexadecimal variation. It should be 00. For example, if you selected 0x23456 for the unique ID value, change the title_id to 0005000012345600.
  • group_id: Set this 8-digit value to the same value that you chose for the unique ID in the title_id. Use leading zeros to complete the value. For example, 00023456.
code/cos.xml Change the permissions value in the p5:mask tag from 0000000000000011 to 0000000000000091, ensuring that you maintain the leading zeros.
If you do not complete this step, the application will not have the appropriate permission required to open data titles and AOC_OpenTitle returns the error AOC_STATUS_INTERNAL_ERROR.
  • title_id: Use the same value that you set for the title_id in code/cos.xml.
  • group_id: Use the same value that you set for the group_id in code/app.xml.
  • add_on_unique_id0: Set the last five digits to the same value that you chose for the AOC unique ID. The value must be between 0x10000 and 0xF7000. Ensure that you do not change the three leading zeros. For example, 00065432. You may set this to the same value that you chose for the unique ID portion of the title_id above.

Configure the AOC XML Files

Use the information in this section as a guide to help you configure the app.xml, cos.xml, and meta.xml files for AOC. Sample versions of the XML files, with the suggested changes in the table, are provided to help you locate and change the items listed in the table. Working configuration files are included for your reference.

File Description of Changes to Make to the AOC<#> files
  • title_id: Select a five-digit hexadecimal value for the unique ID. This should be the same value that you chose in the add_on_unique_id0 field in the meta.xml file for your application above. Set the variation to 00 in AOC1, and 01 in AOC2. For example, if you selected 0x65432 for the application add_on_unique_id0 value, change the title_id to 0005000C16543200 for AOC1 and 0005000C16543201 for AOC2.
  • group_id: Set this 8-digit value to the same group_id value that you used in the application app.xml file. For example, 00023456.
  • title_id: Use the same value that you set for the title_id in the app.xml file for the AOC<#> (AOC<#>/code/app.xml).
  • group_id: Use the same value that you set for the group_id in the app.xml file for the application (code/app.xml).

Installing the AOCTutorial

To Install the AOC by Copying to $CAFE_ROOT/data/mlc

  1. Create the directory $CAFE_ROOT/data/mlc/usr/title/0005000C if it does not already exist.
  2. You may find the AOCTutorial at $CAFE_ROOT/system/src/demo/nn/aoc/AOCTutorial. Copy the AOC1 and AOC2 directories from the AOCTutorial directory to $CAFE_ROOT/data/mlc/usr/title/0005000C.
  3. Rename the AOC1 directory to 1<AOC Unique Id><Variation>. For example, 16543200. 16543200
  4. Rename the AOC2 directory to 1<AOC Unique Id><Variation>. For example, 16543201. 16543201

Running the AOCTutorial

  1. Open a cafe.bat prompt.
  2. Change the working directory to the solution directory.
  3. Export the CAFE_CONTENT_DIR variable to the content directory in the solution directory.
  4. Change the working directory to the "code" directory.
  5. At the command prompt, type caferun AOCTutorial.rpx.


A list of all file contents for files in the content directory and the <AOC#>/content directories. The return status for all AOC functions is AOC_STATUS_OK.

Test AOC

To more thoroughly test AOC and its download process in an environment that is closer to retail, install AOC using a test version of eShop. The test eShop server available to developers is DEV3. It is accessible only through an exclusive whitelist and a special DNS server. Contact your local Nintendo Developer Support Group with the IP addresses that you plan to use to access the server, so the IP address may be added to the whitelist.

In the System Config Tool, on the Network Setting menu, specify the IP address of the DNS server that is listed in the table. Specify the DNS server IP address on each devkit that you use. For general PC use, it may be set on the router rather than on individual PCs.

eShop test server DEV3
DNS server IP address

The AOC must be packaged specifically for IMAS. A wumad of the AOC must be created and converted into an installable directory by using makecfdownloadimage.sh. The contents of the resulting installable directory must be packaged into a zip file, and then uploaded to IMAS. After the zip file is uploaded, a catalog of item sets will be created. For information and instructions about IMAS, see the IMAS Operations Manual for Developers and IMAS Purchase Confirmation Guide, which are available on the Wii U page of your local Nintendo Developer Support Group website.

Testing eShop Purchases

To test eShop purchases from DEV3, install the Wii U Menu Changer and set the DNS server IP address in the connection profile on the devkit to the IP address listed in the table. This redirects the application for eShop to DEV3.

All AOC that were installed for any application by using an SD card must be deleted before testing eShop purchases using DEV3. To uninstall AOC on the Data Manager menu of the System Config Tool.

To download and install the AOC from the test eShop, in the application that you are testing, press the HOME Button to open the HOME Menu. Do not try to access test eShop from the Wii U Menu.

The most convenient way to purchase AOC from the test eShop is to use one of the dummy credit cards that are listed in the following table:

  Visa MasterCard
Number 4444-4444-4444-4448 5454-5454-5454-5454
Expiration date: 12/2030 12/2030
Security code: 123 123
Zip code: any any

Uninstalling AOC

AOC may be deleted in the System Config Tool, on the Data Manager menu. It is important to consider that after a content item is purchased on the test eShop and deleted, you may download it again. But it may not be purchased again. To download the AOC again, perform the same steps as in the original purchase, except the Purchase button is changed to the Redownload button.

To purchase AOC again, delete all accounts, wait approximately one hour, and then recreate an account on the devkit. This clears eShop purchase rights for your devkit in the development environment.


When the AOC is ready for distribution, submit it to Lotcheck. For Lotcheck, the AOC must be properly mastered into a wumad, which requires a more configuration than when you are preparing the wumad for testing purposes.

Mastering a Submission

The Application Configuration Tool is used to master add-on content in the same way that it is used to master any application. To put the tool in AOC mode, select File (F)Create New (N), and then select Save Data File for Addon Contents. Most editable fields are configured the same as they are when mastering a title, with the following exceptions:

After filling in all of the required fields in the Application Configuration Tool, validate the configuration in Tool (T) > Validate (V) and the configuration exported into the AOC root directory. This generates the app.xml, cos.xml, meta.xml, and icon files in the appropriate code and meta directories. The wumad may be generated now with the makecfmaster tool by using the following command at a cafe.bat command prompt

makecfmaster aoc <AOC_ROOT_DIRECTORY> <AOC_NAME>

Finally, as with any submission to Lotcheck, verify the resulting wumad in the Master Editor.

In addition to submitting the wumad to Lotcheck, also submit the catalog via IMAS. Upload your data title to IMAS as you normally do, and then press the Request to Submit button to start the catalog submission. For more information, see the IMAS Operations Manual for Developers on the Wii U Documents page on your local Nintendo Developer Support Group website.


If you have questions or need assistance, contact your local Nintendo Developer Support Group.

Revision History

2014/07/08 Replaced makecfmaster.sh with makecfmaster.exe.
2014/01/21 Terminology change to HOME Menu.
2014/01/14 Removed text on SYSSwitchToEShop function and added reference link to SYSSwitchToEShop function.
2013/06/01 Convert PDF files to HTML.