contract GameCardAttributes is ERC721 {
    // Mapping for token tribe
    mapping(uint256 => string) private _tokenTribes;

    // Mapping for token level
    mapping(uint256 => uint256) private _tokenLevels;

    // Mapping for token experience
    mapping(uint256 => uint256) private _tokenExperiences;

    /**
     * @dev Returns the tribe of a given token ID.
     *      Throws if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query
     */
    function tokenTribe(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId));
        return _tokenTribes[tokenId];
    }

    /**
     * @dev Returns the level of a given token ID.
     *      Throws if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query
     */
    function tokenLevel(uint256 tokenId) external view returns (uint256) {
        require(_exists(tokenId));
        return _tokenLevels[tokenId];
    }

    /**
     * @dev Returns the experience of a given token ID.
     *      Throws if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query
     */
    function tokenExperience(uint256 tokenId) external view returns (uint256) {
        require(_exists(tokenId));
        return _tokenExperiences[tokenId];
    }

    /**
     * @dev Internal function to set the token tribe for a given token.
     *      Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token
     * @param tribe srting tribe to assign
     */
    function _setTokenTribe(uint256 tokenId, string memory tribe) internal {
        require(_exists(tokenId));
        _tokenTribes[tokenId] = tribe;
    }

    /**
     * @dev Internal function to set the token level for a given token.
     *      Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token
     * @param level uint256 level to assign
     */
    function _setTokenLevel(uint256 tokenId, uint256 level) internal {
        require(_exists(tokenId));
        _tokenLevels[tokenId] = level;
    }

    /**
     * @dev Internal function to set the token experience for a given token.
     *      Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token
     * @param experience uint256 experience to assign
     */
    function _setTokenExperience(uint256 tokenId, uint256 experience) internal {
        require(_exists(tokenId));
        _tokenExperiences[tokenId] = experience;
    }
}
function tokenTribe(uint256 tokenId) external view returns (string memory) {
    require(_exists(tokenId));
    return _tokenTribes[tokenId];
}

/**
 * @dev Returns the tribe of a given token ID.
 *      Throws if the token ID does not exist.
 * @param tokenId uint256 ID of the token to query
 */