Adverty

Custom Engine Integration Guide

This guide will help you integrate AdvertySDK into your engine. Since each game engine is unique, this guide uses a common approach applied by the Adverty team across various engine plugins, such as Unity, Cocos2D-x, Godot, and Unreal Engine.

Contents

  • Integration
  • Initializing SDK
  • Start SDK
  • Run SDK
  • Ad Placements
  • Viewability
  • Clicks
  • Extra Features

SDK Minimum Requirements:

  • Android 24. NDK 28+ is recommended. The SDK allows you to build for lower API levels down to API 21, but it will only work on Android 24+ devices.
  • iOS 14.0
  • OSX 13.3
  • Windows 10

Integration

Steps:

  1. Unzip the AdvertySDK.zip file to your project folder or to the folder with third-party libraries.
  2. In your project’s CMakeLists.txt file add:
    
    add_subdirectory(path/to/AdvertySDK)
    target_link_libraries(${YOUR_GAME_NAME} PRIVATE AdvertySDK::AdvertySDK)
            
    Adverty’s CMakeLists.txt file will handle library linking and include directories.

Extra steps for specific platforms:

AdvertySDK integration with Android requires some extra steps.

  1. Enable AndroidX support in your gradle.properties file:
    
    android.useAndroidX=true
    android.enableJetifier=true
                        
  2. Add Adverty’s JNI and Jar libraries to your build.gradle project file.
    
    implementation fileTree(dir: 'RELATIVE_PATH_TO_SDK/lib/Android/libs', include: ['*.jar'])
    implementation fileTree(dir: 'RELATIVE_PATH_TO_SDK/lib/Android/jni', include: ['*.so'])
                      
  3. Add the following permissions to your AndroidManifest.xml file:
    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
                        
  4. AdvertySDK requires the Play Services AdsIdentifier and CustomTabs libraries. The lowest supported play-services-ads-identifier version is 17.1.0. Add the following lines to your build.gradle project file:
    
    implementation 'com.google.android.gms:play-services-ads-identifier:17.1.0'
    implementation 'androidx.browser:browser:1.0.0'
                      

Steps:

  1. Unzip the AdvertySDK.zip file to your project folder or to the folder with third-party libraries.
  2. Move the include folder to your project’s source folder.
  3. Continue with the instructions for your target platform.

Choose target platform:

  1. Enable AndroidX support in your gradle.properties file:
    
    android.useAndroidX=true
    android.enableJetifier=true
                
  2. Add Adverty’s JNI and Jar libraries to your build.gradle project file.
    
    implementation fileTree(dir: 'RELATIVE_PATH_TO_SDK/lib/Android/libs', include: ['*.jar'])
    implementation fileTree(dir: 'RELATIVE_PATH_TO_SDK/lib/Android/jni', include: ['*.so'])
              
    Alternatively, you can use the provided AdvertyUSDK.aar, but you must then remove the jni and libs folders from the Android folder:
    
    implementation files('RELATIVE_PATH_TO_SDK/lib/Android/AdvertyUSDK.aar')
              
  3. Add the following permissions to your AndroidManifest.xml file:
    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
                
  4. AdvertySDK requires the Play Services AdsIdentifier and CustomTabs libraries. Add the following lines to your build.gradle project file:
    
    implementation 'com.google.android.gms:play-services-ads-identifier:17.1.0'
    implementation 'androidx.browser:browser:1.0.0'
              
  1. Add AdvertyUSDK.a from the libs/iOS folder to your project.
  2. Add Adverty’s PrivacyInfo.xcprivacy file to your project.
  3. Add the following frameworks to your project, as AdvertySDK depends on them:
    • AdSupport.framework
    • CoreGraphics.framework
    • ImageIO.framework
    • WebKit.framework
    • Metal.framework
    • AppTrackingTransparency.framework
    • SafariServices.framework
    • StoreKit.framework
    • VideoToolbox.framework
    • CoreMedia.framework
    • CFNetwork.framework
    • bz2.tbd
    • iconv.tbd
  1. Use AdvertyUSDK.dylib as dynamic library in your project.
  2. Add Adverty’s PrivacyInfo.xcprivacy file to your project.
  1. Use AdvertyUSDK.dll as a DLL library in your project.
  2. Additionally, use AdvertyUSDK.lib if your project requires that linking method.

Initializing SDK


To initialize the SDK, you need to call void LoadAdvertyPlugin(GraphicsInterface* graphicsInterface, LoggerFunctionPointer loggerFuncPtr) and pass the graphics interface data and logger function pointer. AdvertySDK supports multiple graphics APIs on each platform.
  • Android: OpenGL ES 2.0, OpenGL ES 3.1, Vulkan
  • iOS: Metal
  • OSX: Metal
  • Windows: DirectX 11, DirectX12, Vulkan
For example, the following code will initialize the SDK and use OpenGL ES 3.1 for rendering on Android:

static void LogCallback(const char16_t* msg, int level)
{
  PrintToEngineConsole(ToEngineLogLevel(level), msg);
}
GraphicsInterface* graphicsInterface = new AdvertyUSDK::API::OpenGLESGraphicsInterface(
GetMainActivity, AdvertyUSDK::API::TextureCoordinateSystem::YDown,
    AdvertyUSDK::API::CoordinateSystemHandedness::Left, GL_RGBA8, GL_SRGB8_ALPHA8,
    AdvertyUSDK::API::GraphicsType::OpenGLES31);

AdvertyUSDK::API::LoadAdvertyPlugin(graphicsInterface, LogCallback);
The SDK is now initialized and ready to receive other API calls. To unload the SDK, call void UnloadAdvertyPlugin();. This call is rarely used and is only useful for fine-grained control over the SDK lifetime.

Start SDK


The SDK is generally designed to share its lifetime with the application. Call void Start(LaunchData launchData); at the beginning of the app and void Stop(); at the end of the app.
Example of a Start call:

    AdvertyUSDK::API::LaunchData launchData{};
    launchData.apiKey = "YOUR_API_KEY";
    launchData.sandboxMode = false; // set to true if you want to use sandbox mode
    launchData.userData = {}; // fill user data if available
    launchData.callbacks = {}; // fill callbacks to track SDK events
    launchData.engineData = {}; // fill engine data for statistics
    launchData.enableImpViz = false; // enable impression visualization (debug feature)
    AdvertyUSDK::API::Start(launchData);
  

Run SDK


After the SDK is initialized and the start parameters are provided, you must launch a heartbeat for the SDK. Call void Update(); every frame in your Game Thread. This will run all internal SDK logic. To perform graphics operations, you need to call void RenderUpdate(); every frame in your Render Thread. The SDK tracks if RenderUpdate() is called. If not, it will self-terminate with a corresponding error log.

void Game::GameThreadTask()
{
  AdvertyUSDK::API::Update();
}

void Game::RenderThreadTask()
{
  AdvertyUSDK::API::RenderUpdate();
}

Ad Placements


AdPlacement works as a container for the ad texture. You must implement your own class that will handle the SDK callbacks related to ad placements. A placement can be registered with int RegisterAdPlacement(AdPlacementDescription description, AdPlacementCallbacks callbacks); and unregistered with void UnregisterAdPlacement(int id);. These methods must be called at the beginning and end of the placement lifecycle.
Example of placement registration:

class AdvertyAdPlacement : public Object
{
  AdvertyAdPlacement()
  {
    AdvertyUSDK::API::AdPlacementDescription description;

    AdvertyUSDK::API::AdPlacementCallbacks callbacks{};
    callbacks.onRegisterSuccess = OnAdvertyPlacementRegistered;
    callbacks.onAdPlacementActivated = OnAdvertyPlacementActivated;
    callbacks.onRegisterFailure = OnAdvertyPlacementFailedToRegister;
    callbacks.onViewabilityCheck = OnAdvertyViewabilityDataRequired;

    auto size = getObjectSizeInUnits();
    description.width = size.width;
    description.height = size.height;
    description.senderObj = this;
    description.allowVideo = allowVideo;
    description.maxSize = AdvertyUSDK::API::AdPlacementTextureSize::Medium;

    id = AdvertyUSDK::API::RegisterAdPlacement(description, callbacks);
  }
  ~AdvertyAdPlacement()
  {
    AdvertyUSDK::API::UnregisterAdPlacement(id);
  }

  int id;
}
As you see, we provided callbacks to track the placement lifecycle. The SDK will call these callbacks. Let’s handle those callbacks:

static void OnAdvertyPlacementRegistered(const AdvertyUSDK::API::AdPlacementRegisterData registerData)
{
  auto* placement = static_cast<AdvertyAdPlacement*>(registerData.senderObj);
  placement->nativeData = registerData.nativeData; // Store texture data to apply once the placement is activated.
}

// Once the placement is activated, we can create a texture and apply it to the placement.
static void OnAdvertyPlacementActivated(void* targetObject)
{
  auto* placement = static_cast<AdvertyAdPlacement*>(targetObject);
  // Create engine texture from native texture. SDK always returns an RGBA8 texture in UNORM format (GL_RGBA8, VK_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, etc.)
  auto texture = Engine::CreateTexture(placement->nativeData.textureBuffer, placement->nativeData.width, placement->nativeData.height, Engine::TextureFormat::RGBA8, Engine::TextureType::2D);
  // Apply texture to placement object, now the placement will be able to render the ad.
  Engine::SetObjectTexture(placement, texture);
}

static void OnAdvertyPlacementFailedToRegister(void* targetObject)
{
  auto* placement = static_cast<AdvertyAdPlacement*>(targetObject);
  //Handle failed placement registration.
}

Viewability


Viewability is an essential part of the SDK validation system. To maintain precise visibility metrics, the SDK continuously polls the onViewabilityCheck callback sub-second. The engine must provide a set of data that will allow the SDK to calculate placement visibility on screen. The SDK supports two types of checks:
  • Clip space check
  • Screen space check
The clip space check is used in a 3D environment and requires mesh data and camera data.

static void OnAdvertyViewabilityDataRequired(void* targetObject)
{
  auto* placement = static_cast<AdvertyAdPlacement*>(targetObject);

  float modelMatrixArray[16];
  float viewMatrixArray[16];
  float projectionMatrixArray[16];

  //Get placement's model matrix
  Engine::Matrix4x4 modelMatrix = placement->GetTransform().GetModelMatrix();

  //Convert to float array
  MatrixToFloatArray(modelMatrix, modelMatrixArray);

  //Get the active camera projection and view matrices
  Engine::Camera* camera = Engine::GetCamera();
  
  Engine::Matrix4x4 projectionMatrix = camera->GetProjectionMatrix();
  MatrixToFloatArray(projectionMatrix, projectionMatrixArray);

  Engine::Matrix4x4 viewMatrix = camera->GetViewMatrix();
  MatrixToFloatArray(viewMatrix, viewMatrixArray);

  AdvertyUSDK::API::ClipSpaceViewabilityData viewabilityData;
  viewabilityData.AdPlacementId = GetId();
  viewabilityData.Vertices = placement->GetMesh()->GetVertices();
  viewabilityData.Normals = placement->GetMesh()->GetVertexNormals();
  viewabilityData.VertexCount = placement->GetMesh()->GetVertexCount();
  viewabilityData.ModelMatrix = modelMatrixArray;
  viewabilityData.ViewMatrix = viewMatrixArray;
  viewabilityData.ProjectionMatrix = projectionMatrixArray;
  viewabilityData.ScreenWidth = camera->GetViewRect().Width();
  viewabilityData.ScreenHeight = camera->GetViewRect().Height();
  viewabilityData.RendererEnabled = placement->IsRendererEnabled();

  AdvertyUSDK::API::SendDataForViewabilityCheck(viewabilityData);
}
The screen space check is used in a 2D environment and requires the placement corner positions on the screen and the screen size.

static void OnAdvertyViewabilityDataRequired(void* targetObject)
{
  auto* placement = static_cast<AdvertyAdPlacement*>(targetObject);
  vec2 corners[4] = placement->GetCornersAsPixels();

    int points[8];
    for (int i = 0, j = 0; i < 4; i++, j += 2)
    {
        points[j] = static_cast<int>(corners[i].x);
        points[j + 1] = static_cast<int>(corners[i].y);
    }

    auto screenSize = Engine::GetScreenSize();

    AdvertyUSDK::API::ScreenSpaceViewabilityData viewabilityData{};
    viewabilityData.AdPlacementId = placement->GetId();
    viewabilityData.PlacementPointsOnScreen = points;
    viewabilityData.PointsCount = 4;
    viewabilityData.ScreenWidth = screenSize.width;
    viewabilityData.ScreenHeight = screenSize.height;
    viewabilityData.RendererEnabled = placement->IsRendererEnabled();

    AdvertyUSDK::API::SendDataForScreenSpaceViewabilityCheck(viewabilityData);
}

Clicks


Clickable ads generate more revenue. Engine developers should implement click handling logic and pass the click event to the SDK once the user clicks on the placement.

void AdvertyAdPlacement::OnObjectClicked()
{
  AdvertyUSDK::API::ClickOnAdPlacement(id);
}

Extra Features


The SDK delivers a few extra features that allow you to refine control over SDK behavior.

  • Impression Visualization – Enable impression visualization to see which placement is causing an impression event on the assigned ad.
    
    // Enable impression visualization before calling Start
    AdvertyUSDK::API::LaunchData launchData = {};
    // ...
    launchData.enableImpViz = true;
    AdvertyUSDK::API::Start(launchData);
          

  • Ad Refreshing Control – allows you to control whether the SDK is allowed to ask for new ads or not.
    AdvertyUSDK::API::EnableAdRefresh() – will enable ad refreshing. It’s the default behavior.
    AdvertyUSDK::API::DisableAdRefresh() – will disable ad refreshing. The SDK will not ask for new ads until AdvertyUSDK::API::EnableAdRefresh() is called.

  • Ad Preloading – allows you to preload ads once the SDK is started. Preloaded ads will be used on placements prior to asking Adverty servers for new ads. Contact Adverty to enable this feature for your project.
    
    void StartAdverty()
    {
      // Call start
      AdvertyUSDK::API::Start(launchData);
    
      std::vector<AdvertyUSDK::API::PreloadAdExtent> preloadExtents;
      preloadExtents.push_back({200, 300});
      preloadExtents.push_back({500, 1000});
      preloadExtents.push_back({800, 200});
      // Preload ads. Call after Start, otherwise it will be ignored.
      AdvertyUSDK::API::PreloadAds((int)preloadExtents.size(), preloadExtents.data());
    }
          
  • iab
  • iab
  • Tag
  • IAB Europe