Cocos2d-x integration guide

Add BugSnag to your Cocos2d-x 3.1+ games for Android, iOS, and macOS.

New to BugSnag? Create an account

Installation

Download the latest bugsnag-cocos2dx release from GitHub, unzip it, and move the bugsnag directory into your app’s root directory.

The latest available version of bugsnag-cocos2dx is v2.0.1.

Add this subdirectory to the bottom of your root CMakeLists.txt file and link the dependency:

if(ANDROID OR APPLE)
    add_subdirectory(bugsnag)
    target_link_libraries(${APP_NAME} bugsnag-cocos2dx ${BUGSNAG_LINKER_FLAGS})
endif()

The next steps depend on your supported platforms.

Android

Add the BugSnag plugin to the bottom of proj.android/settings.gradle:

// ...
include ':bugsnag-cocos2dx'
project(':bugsnag-cocos2dx').projectDir = new File(settingsDir, '../bugsnag/android/bugsnag-plugin-android-cocos2dx')

Add flatDir as a repository and the BugSnag project as a dependency to your Module Gradle Settings in proj.android/app/build.gradle:

repositories {
    flatDir {
        dirs '../../bugsnag/android/libs'
    }
}
dependencies {
    // ...
    implementation project(':bugsnag-cocos2dx')
}

iOS and macOS

Select your game target’s General tab and drag BugsnagCocos2dx.xcframework from the bugsnag/cocoa directory into the Frameworks, Libraries and Embedded Content section. Mark it as Do Not Embed.

Basic configuration

To identify your app in the BugSnag dashboard, you’ll need to configure your BugSnag API key.

In order to capture as many errors as possible on each platform, initialize at the closest point to the app launching as possible.

Android

Configure your API key in the <application> tag of your App Manifest file, located at proj.android/app/src/main/AndroidManifest.xml.

<application ...>
  <meta-data android:name="com.bugsnag.android.API_KEY"
             android:value="YOUR-API-KEY-HERE"/>
</application>

You can find your API key in Project Settings from your BugSnag dashboard.

Then import and initialize BugSnag in AppActivity.java:

import com.bugsnag.android.Bugsnag;
import com.bugsnag.android.Configuration;
import com.bugsnag.android.BugsnagCocos2dxPlugin;

public class AppActivity extends Cocos2dxActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.setEnableVirtualButton(false);
        super.onCreate(savedInstanceState);

        if (!isTaskRoot()) {
            return;
        }
        Configuration config = Configuration.load(this);
        config.addPlugin(new BugsnagCocos2dxPlugin());
        Bugsnag.start(this, config);
        // ...
    }
}

iOS

Import and initialize BugSnag in AppController.mm:

#import <BugsnagCocos2dx/BugsnagCocos2dxPlugin.h>

- (BOOL)application:(UIApplication *)application 
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     BugsnagConfiguration *configuration = [BugsnagConfiguration loadConfig];
     [configuration addPlugin:[BugsnagCocos2dxPlugin new]];
     [Bugsnag startWithConfiguration:configuration];
    // ...
}

Configure your API key by adding a bugsnag Dictionary to your Info.plist file:

Set the apiKey in your Info.plist

Or in XML:

<key>bugsnag</key>
<dict>
    <key>apiKey</key>
    <string>YOUR-API-KEY</string>
</dict>

You can find your API key in Project Settings from your BugSnag dashboard.

macOS

Rename main.cpp to main.mm in Xcode and your CMakeLists.txt file and import and initialize BugSnag in main.mm:

#import <BugsnagCocos2dx/BugsnagCocos2dxPlugin.h>

int main(int argc, char *argv[])
{
     BugsnagConfiguration *configuration = [BugsnagConfiguration loadConfig];
     [configuration addPlugin:[BugsnagCocos2dxPlugin new]];
     [Bugsnag startWithConfiguration:configuration];
    // ...
}

Configure your API key by adding a bugsnag Dictionary to your Info.plist file:

Set the apiKey in your Info.plist

Or in XML:

<key>bugsnag</key>
<dict>
    <key>apiKey</key>
    <string>YOUR-API-KEY</string>
</dict>

You can find your API key in Project Settings from your BugSnag dashboard.

Further configuration

If you’d like to configure BugSnag further, check out the configuration options reference for Android or iOS and macOS.

Showing full stacktraces

Uploading mapping files for Android

If you have enabled ProGuard or use the NDK, you will need to send mapping files to BugSnag in order to deobfuscate Android stack traces. Adding the BugSnag Gradle Plugin to your exported Gradle project will perform this task automatically, or you can integrate the BugSnag CLI into your own build process.

Uploading debug symbol maps (dSYMs) for iOS

Send debug symbol (dSYM) files to BugSnag in order to symbolicate native iOS stack traces and show the file and line numbers where an error occurred. Our iOS symbolication guide provides details on how to automate this process.

Reporting unhandled errors

At this point, BugSnag should be installed and configured, and any unhandled exceptions will be automatically detected and should appear in your BugSnag dashboard.

Reporting handled errors

If you would like to send handled errors to BugSnag, you can pass any std::exception or a name and message to the notify function:

#include <BugsnagCocos2dx/Bugsnag.hpp>

// ...

Bugsnag::notify(ex);

Bugsnag::notify("Authorization failed", "Invalid username value");

Sending diagnostic data

Automatically captured diagnostics

BugSnag will automatically capture and attach the following diagnostic data to every exception report:

  • Full stack traces for all threads.
  • App state including running time and time in foreground.
  • Build information including name, version/build and release stage.
  • Device specification including model, OS version and total memory.
  • System state including orientation, free memory, available disk space and battery level.

For more information see Automatically captured data.

Attaching custom diagnostics

It is often helpful to send us additional application-specific diagnostic data, for example the name of a subsystem in which an exception occurred. If you would like to add custom data to your BugSnag error reports, you can use the addMetadata method. Custom data is displayed inside tabs on each exception on your BugSnag dashboard.

#include <BugsnagCocos2dx/Bugsnag.hpp>

// ...

Bugsnag::addMetadata("system", "subsystem", "player mechanics");

Logging breadcrumbs

In order to understand what happened in your application before each crash, it can be helpful to leave short log statements that we call breadcrumbs. The last several breadcrumbs are attached to a crash to help diagnose what events lead to the error.

Automatically captured breadcrumbs

By default, BugSnag captures common events such as:

  • Low memory warnings
  • Device rotation (if applicable)
  • Menu presentation
  • Screenshot capture (not the screenshot itself)
  • Undo and redo
  • Table view selection
  • Window visibility changes
  • Non-fatal errors

Attaching custom breadcrumbs

To attach additional breadcrumbs, use the leaveBreadcrumb function:

#include <BugsnagCocos2dx/Bugsnag.hpp>

// ...

Bugsnag::leaveBreadcrumb("Button clicked",
                         {{"panel", panelName}, {"should restart", "no"}},
                         BreadcrumbType.Navigation);

Identifying users

BugSnag helps you understand how many of your users are affected by each error. In order to do this, we send along a user ID with every exception. By default we will generate a unique ID and send this ID along with every exception from an individual device.

If you would like to override this identifier or add additional information, use setUser:

#include <BugsnagCocos2dx/Bugsnag.hpp>

// ...

Bugsnag::setUser("id123", "user@example.com", "User Name");

Session tracking

BugSnag tracks the number of “sessions” that happen within your application. This allows you to compare stability scores between releases and helps you to understand the quality of your releases.

Sessions are captured and reported by default. This behaviour can be disabled using a configuration option on Android and iOS/macOS.

Using this option, BugSnag will report a session each time:

  • The app is launched
  • The app enters the foreground for the first time in 60 seconds

If you want control over what is deemed a session, you can switch off automatic session tracking and manage the session lifecycle using startSession, pauseSession, and resumeSession:

#include <BugsnagCocos2dx/Bugsnag.hpp>

// ...

Bugsnag::startSession(); // Start a new session

Bugsnag::pauseSession(); // Pause the current session

Bugsnag::resumeSession(); // Resume a paused session

Next steps