bb_game_state.html 12.1 KB
<html>

<head>
        <title>BB Game State Support</title>
</head>
<body>

<center>
<h1>BB Game State Support</h1>
</center>

<h2>Overview</h2>

The n64 game state can potentially be stored to the cartridge on
eeprom (4Kb, 16Kb), 1Mb flash, and 256Kb sram. Game state can also
be stored on a 32KB controller pak which is inserted in a controller.
Games use various combination of these storage types, and a
summary may be found <a href="game_dev/Nintendo_game_data.html">here</a>.
The cartridge storage mechanisms only hold data associated
with the game stored on the cartridge. However, the controller pak
is a shared storage medium for games. As a result, game data
written by one game can, at the very least, be deleted by another.
The controller pak also enables state sharing between players, such
one player using another's run through a race course as ghost
competitor.
<p>
The following apis and mechanisms were provided by libultra for
accessing the above storage means:
<ul>
  <li> Controller Pak: osPfs. Although the api is general enough
       to manage arbitrary sized paks, only 32KB paks are used in
       practice.
  <li> Catridge EEPROM: osEeprom.
  <li> Catridge Flash: osFlash.
  <li> Catridge SRAM: there is no dedicated api for managing flash.
       The access should use the osEpi api.
</ul>
<p>
The BB will provide libultra api implementations that emulate the
above, and the strategy is summarized <a href="hwimpact.html">here</a>.
For the sake of this document, it suffices to know that the
emulated storage provided by these mechanisms will reside in system
memory (most likely dram) and be managed by a coordinated effort
by the new libultra, the system app, and the secure kernel.
<p>
Since the BB infrastructure also includes the depot and servers,
we would like to leverage this and utilize the state information
to foster competition and game purchase. To enable this and
compatibility, the primary goals of the BB game state support are to:
<ul>
  <li> present the game with compatible interfaces for state storage
  <li> allow the "cartridge" state to be signed such that the depot
       (leveraging servers) may assign merit based rewards based on
       game play, and potentially post results
  <li> enable the more compelling modes of inter-player state
       sharing provided by the controller pak
</ul>
The controller pak utilization is covered in more detail later, but
as a general rule we assume that it is the only mechanism used to
share state. Also, we assume that no merit based information (such
as level achieved during play) will be stored on the controller pak.
These assumptions allow import of another players pak information
for sharing such that game progress is not effected.
<p>
This document describes how state is managed to accomplish the above
goals. First, the controller pak use model is described for a selected
group of games, then an implementation description is provided which
covers how state is stored on the bbcard, how fields in the ticket
support state, and how the sysapp provides a UI and generally manages
state with secure kernel support.


<h2>Controller Pak Utilization</h2>

The table below indicates how the controller pak is used by a sample
of games. The sample includes Nintendo first and second party titles,
excluding Rare games 
(<a href="game_dev/Nintendo_game_data.html">game details</a>). 
Typically, the controller pak is 32KB, and the minimal
storage unit is a 256B page. The controller pak api supports creation
of up to 16 files (notes) on a given pak.

<p>

<table BORDER=1>
  <caption><b>n64 Game Controller Pak Usage</b></caption>
  <tr ALIGN=CENTER>
    <th>Game
    <th>What is Stored
    <th>Pages 
    <th>Storage and Copy Modes
  <tr>
    <td>ExciteBike
    <td>Ghost rides through track. <br> Individually created tracks.
    <td>40/ghost <br>4/track
    <td>Delete notes on any connected pak. <br> Direct save ghost/track 
        to any connected pak.
  <tr>
    <td>WaveRace
    <td>Characteristics of crafts. <br>
        Modified contestant names. <br>
	Racing records (course/lap). <br>
    <td>2
    <td>nosPak delete notes on first pak found. <br>
        Transfer (any data) catridge EEPROM to/from first pak.
  <tr>
    <td>MarioKart
    <td>Ghost rides for 2 different tracks.
    <td>121
    <td>nosPak Delete notes on first pak found. <br>
        Ghosts directly stored to pak. <br>
        Copy from pak in ctrl 2 TO pak in ctrl 1.
  <tr>
    <td>NBACourtside
    <td>Season Stats. <br>
        Rosters. <br>
	Create a fixed number of players. <br>
	Choose look and abilities. <br>
	Abilities change with play. <br>
    <td>107
    <td>Always choose pak (or catridge) to use at startup. <br>
        Can delete while cycling paks for above choice. <br>
        Store at fixed milestones. <br>
  <tr>
    <td>AnimalForest
    <td>Game character progress/possesions/characteristics.
    <td>103
    <td>nosPak delete notes on first pak found. <br>
        Some data is stored directly to pak. <br>
        On boarding a train to exit the village (and become a visitor
	at another village), character state is copied from cartridge
	to pak. <br>
	Upon arriving home, altered character state is copied back
	to cartridge??? <br>
</table>

<p>
<b>NOTE:</b> when NBA Courtside 2 came out, the controller pak support
was removed in favor of catridge storage. This game didn't pose a very
compelling need for separate pak and catridge storage, so isn't a good
model to drive our sharing decisions.


<h2>BB Controller Pak Support</h2>

The key points for the controller pak management are:
<ul>
  <li> The bb will only support a single logically connected
       controller pak once a game has started.
  <li> Each game has it's own logical controller paks as part of
       it's state. That is, a game's logical pak will never hold
       notes from another game.
  <li> Ticket meta-data will contain the required number of per-pak
       pages for the game.
  <li> Each game will be written to bbcard with space for two
       logical paks pre-allocated, each having the number of pages
       indicated in the ticket. One pak will initially be the default,
       and the other will initially be the default for import
       operations.
  <li> The names for a game's two logical paks will be pre-defined
       and not user assignable. This is done to avoid imposing a
       requirement that the user input text in the system app.
  <li> New per-game paks (of the same size as the original) may NOT
       be created, but an import from another bbcard, or the depot,
       is supported. This import would overwrite data in one of the two
       pre-allocated logical paks.
  <li> The ui at game launch will automatically offer a choice of paks 
       (to be used during the ensuing game play) only if the second
       logical pak has been used. A TBD mechanism will be implemented
       to allow choice of paks if the user takes specific action (such
       as holding a button at the appropriate time). This is done to
       avoid confusing a novice user early in the bb gaming
       experience.
  <li> The storage mechanism for pak data will provide an indication
       of the pak most recently used.
  <li> Although pak data is signed along with the other game state, 
       the import does not check for authenticity. This is OK since
       we assume no merit rewards will be provided based on pak data.
</ul>

<p>
The pak state is stored in the same file with other game state.
Although pre-allocating space for two logical paks may cost up
to 32KB of bbcard storage, it will greatly simplify the UI.


<h2>BBCard State File</h2>

As indicated <a href="bb_player_sw/file_conventions.html">here</a>,
each game stored on the bbcard with the filename game_cid.gam
(game_cid is the ascii-hex representation for the 32 bit cid)
will have a state file named game_cid.sta. This file will contain
the following (in big-endian format).
<ul>
  <li> 32 bit CID.
  <li> 32 bit set of flags. currently the only flag defined is
       used to indicate which logical controller pak was most
       recently used (the lowest order bit is used for this
       purpose).
  <li> space for the 2 logical controller paks used by this game.
       the number of bytes is determined from the game ticket.
  <li> combined storage for all catridge-based storage provided
       by n64 (ordering and relation to each other TBD). the
       size of this storage area is determined from the game
       ticket.
  <li> a 512bit ECC signature using the BB private key. the signature
       covers the entire preceding state blob in this file.
</ul>
<p>
Although the entire state file is signed, the import for
controller pak data will not check that the signature is
consistent. However, only the pak data is imported, and
the system app will insure the new state data bundle (catridge
portions remain unchanged) is properly signed by the
secure kernel before saving the import to bbcard flash.
The state file will be checked before game launch, and if
the signature is not valid the sysapp will zero out the
non-pak data to re-initialize.
<p>
The signature and handling of import will allow the depot/servers
to permorm a fool-proof determination of catridge state
for assigning merit prizes, posting scores on the web to
foster competition, and other state-based activities.
<p>
It is worth emphasizing that when the depot places the .gam
file on the bbcard, it will also need to pre-allocate the
associated .sta file to have the space indicated in the ticket.


<h2>Sysapp State Management</h2>

The sysapp handling of controller pak data for import/sharing was
described earlier. Ignoring the import steps for now, and assuming
the sysapp is providing a choice of controller paks, the flow
for state management is:
<ul>
  <li> sysapp allows user to choose a game to launch
  <li> sysapp reads the games .sta file from bbcard
  <li> sysapp call a sk api to verify the signature
       and data in the .sta file match. if there is
       not a match, the sysapp zeros the data in the
       catridge-storage sections, and rewrites the
       .sta file (signed by sk).
  <li> sysapp copies the state data in the .sta file
       to the address indicated in the ticket.
  <li> sysapp makes the normal sk calls to launch
       an app (i.e., non state-centric).
  <li> sk ultimately passes control to the loaded app.
       it internally maintains the address determined
       by the ticket where the state is stored.
  <li> game osInitialize() has code to call the skapi
       to determine the address where state will be
       stored, and the sizes for each type.
  <li> game exits, making sure the state is at the
       correct address (a copy may be necessary, but
       this is the game's responsibility).
  <li> sk gains control and launches the sysapp with
       arguments indicating state must be stored for
       a game with a given content id.
  <li> sysapp calls the skapi to sign the state data.
  <li> sysapp writes the data to the bbcard.
</ul>
<p>
The skapi functions required by this flow (in addition to
normal launching described elsewhere):
<ul>
  <li> sign the state data
  <li> verify the state data signature
  <li> provide state information (no ticket is
       passed in as arg). used by both game and sysapp to determine
       state saving info stored in ticket. the data becomes valid
       after the sysapp makes the "begin" skapi call for game launch,
       which passes in the license to the sk. the sk must maintain
       the game-state information as persistent state after the
       "begin" launch call.
</ul>

<h2>Ticket Fields Supporting State</h2>

The ticket fields are used to inform the system app how much
storage is required for each state saving mode the n64 supported.
Also, they indicate where in memory the sysapp should place
the state before the game is run, and where it should find it
when the game finishes.
<p>
The following fields are used (names may change in the actual header):
<ul>
  <li> u32 stateStorage: lower 8 bits are the number of controller
       pak pages required. Upper bits hold flags indicating if the
       EEPROM is present for 4 and 16 Kb, the 1Mb Flash is present, 
       and the 256Kb SRAM is present.
  <li> u32 stateAddr: physical address in DRAM where the state
       storage emulation will reside.
</ul>


</body>
</html>