Game Admin Module

Overview

The game_admin module manages a resource account for each game that uses the AptosArcadeCore package. Each game is identified by a unique GameType struct, which is used as a witness to authenticate the origin of game operations.

Game Admin

The SignerCapability for GameType's game admin resource account is stored in a GameAdmin<GameType> resource, which is owned by the address that defines the GameType struct.

/// holds the `SignerCapability` for the game admin account
struct GameAdmin<phantom GameType> has key {
    /// `SignerCapability` for the game admin account
    signer_cap: SignerCapability
}

A GameAdmin<GameType> resource is created by calling the initialize function. The function asserts that the address of game_admin equals the address of the account that defines the GameType struct.

/// initializes the game admin for the given `GameType`
/// `game_admin` - must be the deployer of the `GameType` struct
/// `witness` - ensures that the `GameType` struct is the same as the one that was deployed
public fun initialize<GameType: drop>(
    game_admin: &signer, 
    _witness: &GameType
): GameAdminCapability<GameType>

Further game admin operations require the use of a GameAdminCapability<GameType>, which utilizes the capability pattern.

/// used to access game admin functions
struct GameAdminCapability<phantom GameType> has drop, store {}

A GameAdminCapability<GameType> can be created using the create_game_admin_capability<GameType> function, which verifies that the resource account for GameType has been initialized and that the address of game_admin is the deployer of the GameType struct.

/// creates a game admin capability for the given `GameType`
/// `game_admin` - must be the deployer of the `GameType` struct
/// `witness` - ensures that the `GameType` struct is the same as the one that was deployed
public fun create_game_admin_capability<GameType: drop>(
    game_admin: &signer, 
    _witness: &GameType
): GameAdminCapability<GameType>

The GameAdminCapability<GameType> struct is then used to create collections, mint tokens, and perform other administrative functions such as creating matches, setting match results, creating stats, and creating achievements.

Collections

The game_admin module facilitates the creation of Aptos Token V2 collections and provides several options to control the distribution of tokens from the collection. Beyond the standard fields of the Aptos Token V2 Collection Resource, the game_admin::Collection resource contains three additional fields:

/// holds information about a collection
struct Collection has key {
    /// whether the tokens can be transferred after mint
    soulbound: bool,
    /// whether an account that is not the game admin can mint
    mintable: bool,
    /// mapping from minter address to minted object address
    /// option::none for collections that are not one-to-one
    one_to_one_mapping: Option<SmartTable<address, address>>
}
  • soulbound - whether the token from a collection can be transferred after mint. Tokens like a player's gamer profile are soulbound, while in-game items like swords and guns are not, allowing them to be traded on a marketplace

  • mintable - whether an account which is not the game_admin can mint tokens from the collection. Gamer profiles - which are unique to a player - are mintable while Match tokens, which are governed by the game_admin, are not

  • one_to_one_mapping - if a collection requires that a player only be able to mint one token per collection, the Option for this field is filled with a SmartTable<address, address>. Using address, rather than a boolean, facilitates a lookup of a particular account's token address. If a collection does not limit the number of tokens per player, then this field equals option::none()

Collections can only be created by the game_admin, thus requiring a GameAdminCapability<GameType> as a parameter. The caller must additionally provide the standard fields for an Aptos Token V2 collection, as well as values for the previously outlined extensions.

/// creates a collection for the given `GameType` under the game admin resource account
/// `game_admin_cap` - must be a game admin capability for the given `GameType`
/// `description` - description of the collection
/// `name` - name of the collection
/// `royalty` - royalty of the collection
/// `uri` - uri of the collection
/// `soulbound` - whether the collection is soulbound
/// `can_player_mint` - whether the collection allows player mint
/// `one_to_one` - whether the collection is one-to-one
public fun create_collection<GameType>(
    _game_admin_cap: &GameAdminCapability<GameType>,
    descripiton: String,
    name: String,
    royalty: Option<Royalty>,
    uri: String,
    soulbound: bool,
    can_player_mint: bool,
    one_to_one: bool,
)

Tokens

Once a collection has been created, tokens can be minted by the game_admin, or by external accounts if the mintable flag is true for the collection.

The game_admin can always mint from a collection with the mint_token_game_admin function. In addition to the fields needed to mint a standard V2 token, the game_admin must provide a to_address to which the token will be minted.

/// mints a token for `collection_name` for the given `GameType` under the game admin resource account
/// `game_admin_cap` - must be a game admin capability for the given `GameType`
/// `collection_name` - name of the collection
/// `token_description` - description of the token
/// `token_name` - name of the token
/// `royalty` - royalty of the token
/// `uri` - uri of the token
/// `to_address` - address to mint the token to
public fun mint_token_game_admin<GameType>(
    _game_admin_cap: &GameAdminCapability<GameType>,
    collection_name: String,
    token_description: String,
    token_name: String,
    royalty: Option<Royalty>,
    uri: String,
    to_address: address
): ConstructorRef

If a collection is mintable, an external account can mint a token using the mint_token_external function

/// mints a token for `collection_name` for the given `GameType` to the minter; collection must be mintable
/// `minter_cap` - MinterCapability for GameType
/// `collection_name` - name of the collection
/// `token_description` - description of the token
/// `token_name` - name of the token
/// `royalty` - royalty of the token
/// `uri` - uri of the token
/// `soulbound` - whether the token is soulbound
public fun mint_token_external<GameType>(
    minter_cap: &MinterCapability<GameType>,
    collection_name: String,
    token_description: String,
    token_name: String,
    royalty: Option<Royalty>,
    uri: String,
): ConstructorRef

Last updated