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.
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.
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:
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.
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.
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:
- Unzip the AdvertySDK.zip file to your project folder or to the folder with third-party libraries.
- In your project’s CMakeLists.txt file add:
Adverty’s CMakeLists.txt file will handle library linking and include directories.add_subdirectory(path/to/AdvertySDK) target_link_libraries(${YOUR_GAME_NAME} PRIVATE AdvertySDK::AdvertySDK)
Extra steps for specific platforms:
AdvertySDK integration with Android requires some extra steps.-
Enable AndroidX support in your gradle.properties file:
android.useAndroidX=true android.enableJetifier=true -
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']) -
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" /> - 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:
- Unzip the AdvertySDK.zip file to your project folder or to the folder with third-party libraries.
- Move the include folder to your project’s source folder.
- Continue with the instructions for your target platform.
Choose target platform:
-
Enable AndroidX support in your gradle.properties file:
android.useAndroidX=true android.enableJetifier=true -
Add Adverty’s JNI and Jar libraries to your build.gradle project file.
Alternatively, you can use the provided AdvertyUSDK.aar, but you must then remove the jni and libs folders from the Android folder:implementation fileTree(dir: 'RELATIVE_PATH_TO_SDK/lib/Android/libs', include: ['*.jar']) implementation fileTree(dir: 'RELATIVE_PATH_TO_SDK/lib/Android/jni', include: ['*.so'])implementation files('RELATIVE_PATH_TO_SDK/lib/Android/AdvertyUSDK.aar') -
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" /> - 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'
- Add AdvertyUSDK.a from the libs/iOS folder to your project.
- Add Adverty’s PrivacyInfo.xcprivacy file to your project.
-
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
- Use AdvertyUSDK.dylib as dynamic library in your project.
- Add Adverty’s PrivacyInfo.xcprivacy file to your project.
- Use AdvertyUSDK.dll as a DLL library in your project.
- 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
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:
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
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()); }



