Skip to content

Provisioning Features

The Scorbit SDK provides several features that can be integrated into your game's menu system, allowing players to pair their device and manage their connection to the Scorbit service. These game menu features will establish Scorbit's pairing and generally only need to be set up once, when the user first activates the feature. Not all games have visual displays capable of navigating menues, so Scorbit provides different ways of accomplishing this. Often using the Scorbit app as a companion device, or a Scorbit Desktop Utility, will aid the machine owner in this process.

Game Menu Prerequisites

It is assumed that the core function of setting up the game's IP connectivity will be previously enabled by the game code. For example, a game menu that has an option to set a WiFi SSID and Password, or the ability to plug in an Ethernet cable using DHCP.

A Word about Network Time

Connecting an arcade game makes that game into an Internet of Things device (IoT), and like all IoT devices, it must be secure. Having accurate network time is an important piece of that security, which is why all modern operating system manages time automatically. If the base OS is Linux-based, or even Windows, this generally is managed by the system once connected. Batteries get old, and sometimes if time slips significantly it can cause authentication issues, so it's best to do a clean time sync on power up or reboot. While Scorbit will acquire time via the platform directly once connectivity is established, we recommend implementation of ntp, timesyncd, or chrony to prevent slippage and keep network transactions working smoothly.

Pairing from a Game Menu

There are two methods for pairing a device: QR Codes and Six Digit Alphanumeric Codes. In both cases, the code passes a unique identifier that tells the Scorbit app or client what UUID should be associated with that specific machine. The QR code version provides a deeplink URL that tells the Scorbit app to install itself if it doesn't exist, then create a new virtual machine, and then pair the two. The alphanumeric code version essentially does the same thing, but requires that the user enter the code manually into the app when prompted.

QR Code Pairing

To generate a QR code that contains the pairing deeplink:

const char* get_pair_link(sb_game_handle_t state) {
    // Get the pairing deeplink to encode as QR
    return sb_get_pair_deeplink(state);
}
std::string get_pair_link(scorbit::GameState& gs) {
    // Get the pairing deeplink to encode as QR
    return gs.getPairDeeplink();
}
def get_pair_link(gs):
    # Get the pairing deeplink to encode as QR
    return gs.get_pair_deeplink()

Short Code Pairing

Similarly, a request for a 6-character pairing code for situations such as 14-segment displays:

void request_pair_code(sb_game_handle_t state) {
    // Request a short pairing code
    sb_request_pair_code(state, pair_code_callback, NULL);
}

void pair_code_callback(sb_error_t error, const char* code, void* user_data) {
    if (error == SB_EC_SUCCESS) {
        // Display the pairing code to the user
        display_code(code);
    }
}
void request_pair_code(scorbit::GameState& gs) {
    // Request a short pairing code
    gs.requestPairCode([](scorbit::Error error, const std::string& code) {
        if (error == scorbit::Error::Success) {
            // Display the pairing code to the user
            display_code(code);
        }
    });
}
def request_pair_code(gs):
    # Request a short pairing code
    gs.request_pair_code(lambda error, short_code: display_code(short_code) if error == 0 else None)

Detaching (Unpairing)

If a user sells their game to another person, Scorbit has to know somehow to disassociate the UUID with the original owner's virtual machine. This can be done via the app through a tool to allow the detaching, but we have found that users often forget. For security reasons, this means the new owner has difficulty pairing until the old pairing is terminated. Therefore, all game menus should have a way to reset or "detach" the machine directly, without using the app:

void unpair_device(sb_game_handle_t state) {
    // Request device unpairing
    sb_request_unpair(state, unpair_callback, NULL);
}

void unpair_callback(sb_error_t error, const char* reply, void* user_data) {
    if (error == SB_EC_SUCCESS) {
        // Device successfully unpaired
        handle_unpair_success();
    } else {
        // Handle unpairing error
        handle_unpair_error(error);
    }
}
void unpair_device(scorbit::GameState& gs) {
    // Request device unpairing
    gs.requestUnpair([](scorbit::Error error, const std::string& reply) {
        if (error == scorbit::Error::Success) {
            // Device successfully unpaired
            handle_unpair_success();
        } else {
            // Handle unpairing error
            handle_unpair_error(error);
        }
    });
}
def unpair_device(gs):
    # Request device unpairing
    gs.request_unpair(lambda error, reply: handle_unpair_success() if error == 0 else handle_unpair_error(error))

Pairing Methods

Offer both QR and short code pairing when possible to accommodate different display capabilities.

Status Checking

Always verify the authentication status before attempting pairing or unpairing operations.

User Feedback

Provide clear feedback to users during pairing and unpairing operations.

Status Checking

To determine the current pairing status so it can be displayed on the game menu or during various screens and attract modes, you can monitor the authentication and pairing status:

void check_status(sb_game_handle_t state) {
    sb_auth_status_t status = sb_get_status(state);
    switch (status) {
        case SB_NET_AUTHENTICATED_PAIRED:
            // Device is paired and ready for score submission
            display_paired_status();
            break;
        case SB_NET_AUTHENTICATED_UNPAIRED:
            // Device is authenticated but needs pairing
            display_pairing_instructions();
            break;
        case SB_NET_AUTHENTICATTION_FAILED:
            // Authentication failed, may need to check network
            handle_auth_error();
            break;
        case SB_NET_CONNECTING:
            // Currently establishing connection
            display_connecting_status();
            break;
        case SB_NET_DISCONNECTED:
            // Not connected to Scorbit services
            display_disconnected_status();
            break;
    }
}
void check_status(scorbit::GameState& gs) {
    auto status = gs.getStatus();
    switch (status) {
        case scorbit::AuthStatus::AuthenticatedPaired:
            // Device is paired and ready for score submission
            displayPairedStatus();
            break;
        case scorbit::AuthStatus::AuthenticatedUnpaired:
            // Device is authenticated but needs pairing
            displayPairingInstructions();
            break;
        case scorbit::AuthStatus::AuthenticationFailed:
            // Authentication failed, may need to check network
            handleAuthError();
            break;
        case scorbit::AuthStatus::Connecting:
            // Currently establishing connection
            displayConnectingStatus();
            break;
        case scorbit::AuthStatus::Disconnected:
            // Not connected to Scorbit services
            displayDisconnectedStatus();
            break;
    }
}
def check_status(gs):
    status = gs.get_status()
    if status == scorbit.AuthStatus.AUTHENTICATED_PAIRED:
        # Device is paired and ready for score submission
        display_paired_status()
    elif status == scorbit.AuthStatus.AUTHENTICATED_UNPAIRED:
        # Device is authenticated but needs pairing
        display_pairing_instructions()
    elif status == scorbit.AuthStatus.AUTHENTICATION_FAILED:
        # Authentication failed, may need to check network
        handle_auth_error()
    elif status == scorbit.AuthStatus.CONNECTING:
        # Currently establishing connection
        display_connecting_status()
    elif status == scorbit.AuthStatus.DISCONNECTED:
        # Not connected to Scorbit services
        display_disconnected_status()

Common Status Scenarios

Status When It Occurs Recommended Action
AuthenticatedPaired Device successfully paired Enable score submission, show connected status
AuthenticatedUnpaired First-time setup or after unpairing Display pairing QR code or short code
AuthenticationFailed Network issues or invalid credentials Check network connection and device info
Connecting During initial connection or reconnection Show connecting indicator
Disconnected No network connection Check network settings

Status Polling

Check status regularly in your game loop to keep UI indicators current, but avoid checking more frequently than once per second to prevent unnecessary overhead.

Thread Safety

The status check is thread-safe and can be called from any thread in your application.

Best Practices

1. Menu Integration

  • Place pairing options in an accessible menu
  • Provide clear instructions for users
  • Show current pairing status

2. Error Handling

  • Display meaningful error messages
  • Provide retry options when appropriate
  • Log errors for troubleshooting

3. User Experience

  • Show pairing progress indicators
  • Confirm successful operations
  • Guide users through the process