Why use custom data formats on NFC toys?
As we've seen up to now, most of the data stored on NFC toys is not just hidden behind a password, but it's also encrypted.
This is fairly atypical as far as NFC tokens go. Many payment and stored value cards, for example, consider the block passwords enough. How else could game data be stored?
Instead of using them as arbitrary data storage, NFC tokens can store data using the industry-standard NDEF format.
Standard NDEF messages mean standard NDEF code, saving development teams the effort of writing custom NFC token code, and reducing the risk of bugs. Researchers have discovered bugs in how some later series games calculate bonuses based on previous games' data, inadvertently changing values; a common issue with custom code and custom data formats over time.
An argument against NDEF messages might be the overhead of the NDEF message format. However, we've seen both the Skylander and Infinity figures have plenty of empty space on them, and the data storage research we did for Giants suggests there might be an overall space savings to be had.
For example, we discussed two blocks potentially being used to store a nickname of up to fifteen characters.
Giants will only let us enter in names up to 15 letters long. If both of those blocks are 100% dedicated to the nickname, that means there's 32 bytes available for it, but a 15-character limit suggests something more like two bytes per character, possibly to support foreign language characters in Unicode. "Securitoy" is nine characters, so 18 bytes, so it would take up the whole first block and then two bytes in the second block.
That means the game could be reserving two whole blocks of space (four, actually, given it duplicates data), whether or not the player names their character.
NDEF messages include their length, so messages can come one after another, straddling blocks, and even having empty message content for e.g. when the player doesn't name their character.
An NDEF "text" message for an unused nickname could be as short as:
11 01 00 54
That would save 28 bytes. An NDEF "text" message for the "securitoy" nickname could be:
11 01 0c 54 02 65 6e 73 65 63 75 72 69 74 6f 79
That would save 16 bytes. An NDEF "text" message for the "bob" nickname could be:
11 01 06 54 02 65 6e 62 6f 62
We also discussed values for gold, experience, and timestamp.
There isn't a standard "number" NDEF format, but there are custom formats. Here's one that represents gold values from 0 to 65,535 in fifteen bytes, in a standard way, using the custom
nfc.toy:au type. (A shorter custom type name would shorten the record.)
d4 0a 02 6e 66 63 2e 74 6f 79 3a 61 75 93 01
There's also an "unknown" format, which can store binary data of an arbitrary meaning and length. Here's an "unknown" record, storing the same gold value:
d5 00 02 93 01
Of course, that can't have any information about what type of value is stored there; we'd have to know it was gold by location or sequence. "Unknown" formats can have unique IDs, however; here's the same gold example with a one-byte ID, allowing for 255 other types of values elsewhere:
dd 00 02 01 4f 93 01
The MIFARE tags used in Skylanders and Infinity figures support blocks being used for "values" instead of raw data. Intended for use with payment cards, value blocks support incrementing, decrementing, transferring, and resetting values.
Similar to how the Skylander figures duplicate data twice, value blocks store the same value three times within each block, for redundancy and security.
Value blocks can store values from −2,147,483,648 through 2,147,483,647.
Using a value block for individual numbers like gold or experience would mean an entire block would be used for a single value, but it also wouldn't have to be duplicated elsewhere on the figure, and there would be a reduced risk of corruption due to programming bugs manipulating the value inconsistently.