> For the complete documentation index, see [llms.txt](https://docs.brawl3r.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.brawl3r.com/smart-contracts/aptos-arcade-core/game-admin-module.md).

# 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](https://www.move-patterns.com/witness.html) 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.

```rust
/// 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.

```rust
/// 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](https://www.move-patterns.com/capability.html) pattern.

```rust
/// 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.

```rust
/// 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](https://github.com/aptos-labs/aptos-core/blob/2ffffebe67e187e4491f8663d91dae013c4eedd9/aptos-move/framework/aptos-token-objects/sources/collection.move#L50), the `game_admin::Collection` resource contains three additional fields:

```rust
/// 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.

```rust
/// 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.

```rust
/// 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

```rust
/// 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
```
