This is a fork of damnedpie/godot-cas, maintained by Abyss Moth (RimuruDev) for our own game projects.
Godot 3 is NOT supported here. The
godot3module was removed — this fork is Godot 4 only. If you need Godot 3 support, use the upstream repo: https://github.com/damnedpie/godot-casWhat this fork adds on top of upstream:
- Native VPN detection:
isVpnActive()(+ existingisWifiOrMobileInternetEnabled()), handy to gate/adjust ad logic on the game side.- Godot 3 removed — leaner, Godot 4 only.
rebuild_aar.command— one command to rebuild the Godot 4 AAR (Gradle 8.7, JDK 17–22) and drop it into your project's addon.- Tuned for the Abyss Moth ad stack (config-driven mediation/permissions/consent lives in the game project, not here).
Use at your own risk. This fork is shaped around Abyss Moth's needs and is not a general-purpose, supported release — but we do ship it in production and it works fine for us. For the canonical, broadly-tested plugin, prefer upstream.
Warning!
- CAS 4.7.3 tested only for Godot 4.6.3 (Steam version)
- Godot 3 is not supported in this fork (use upstream for Godot 3)
CAS SDK 4.7.3 Android plugin for Godot. Godot 4 only (built against the Godot 4.6.x Android library). For Godot 3 use upstream.
-
Add plugin files (.gd, .gdap, .aar) from the
godot4folder into your project'sandroid/plugins. -
Add
GodotCas.gdas a singleton (autoload) to your project. -
Add your Google AdMob ID to
android/build/AndroidManifest.xml:<application android:label="@string/godot_project_name_string" android:allowBackup="false" android:isGame="true" android:hasFragileUserData="false" android:requestLegacyExternalStorage="false" tools:ignore="GoogleAppIndexingWarning" android:icon="@mipmap/icon"> <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-YOUR_ADMOB_ID_HERE" /> <!-- Other metadata... -->
-
Get your
cas_settings[settings_id].jsonfile from CAS dashboard and put it intoandroid/build/res/rawfolder. -
(Optional) Add
com.google.android.gms.permission.AD_IDpermission to your Android export template if you want to use AD ID (which is usually the case). You can also addandroid.permission.ACCESS_COARSE_LOCATIONandandroid.permission.READ_PHONE_STATEpermissions if your app has real usecases for those (this can improve monetization).
CAS AI provides a Gradle plugin to make integration easier. It injects all the required dependencies, Google AdMob Pub ID, Tenjin (optional) and Ads Identifier (optional) dependencies into your Android build automatically.
To use CAS Gradle plugin, there are some key differences from Manual integration flow that you have to ensure.
- Make sure that Godot CAS config file (.gdap) doesn't contain any dependencies or repositores:
[config]
name="GodotCas"
binary_type="local"
binary="GodotCas.4.6.5.release.aar"
[dependencies]
remote=[]
custom_maven_repos=[]
- Make sure that your
android/build/AndroidManifest.xmlDOES NOT contain Google AdMob Pub ID to avoid conflicts with the injection that CAS Gradle plugin will make.
Now, to include CAS Gradle plugin:
- Go to your
android/build/build.gradleand add CAS Gradle plugin to thepluginssection in the top of the file:
/ Gradle build config for Godot Engine's Android port.
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
// CAS Gradle Plugin
id 'com.cleveradssolutions.gradle-plugin' version "4.6.5"
//...
//...
}- Add the repositories CAS SDK and adapters need to fetch the dependencies (actual informattion here) into the allProjects / dependencies block:
allprojects {
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven { url "https://plugins.gradle.org/m2/" }
maven { url "https://central.sonatype.com/repository/maven-snapshots/"}
// CAS AI repositories
maven {
name = "MintegralAdsRepo"
url = uri("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea")
content { includeGroup("com.mbridge.msdk.oversea") }
}
maven {
name = "PangleAdsRepo"
url = uri("https://artifact.bytedance.com/repository/pangle")
content { includeGroup("com.pangle.global") }
}
maven {
name = "ChartboostAdsRepo"
url = uri("https://cboost.jfrog.io/artifactory/chartboost-ads/")
content {
includeGroup("com.chartboost")
includeGroup("com.iab.omid.library")
}
}
maven {
name = "YSONetworkRepo"
url = uri("https://ysonetwork.s3.eu-west-3.amazonaws.com/sdk/android")
content { includeGroup("com.ysocorp") }
}
maven {
name = "OguryAdsRepo"
url = uri("https://maven.ogury.co")
content {
includeGroup("co.ogury")
includeGroup("co.ogury.module")
}
}
maven {
name = "SmaatoAdsRepo"
url = uri("https://s3.amazonaws.com/smaato-sdk-releases/")
content {
includeGroup("com.smaato.android.sdk")
includeGroup("com.verve")
}
}
maven {
name = "VerveAdsRepo"
url = uri("https://verve.jfrog.io/artifactory/verve-gradle-release")
content {
includeGroup("net.pubnative")
includeGroup("com.verve")
}
}
// Godot user plugins custom maven repos
String[] mavenRepos = getGodotPluginsMavenRepos()
if (mavenRepos != null && mavenRepos.size() > 0) {
for (String repoUrl : mavenRepos) {
maven {
url repoUrl
}
}
}
}
}- Add the
cas{}configuration block somewhere belowplugins{}block. Here's an example of configuration for Optimal Ads with Tenjin and Advertising Identifier included:
// Gradle build config for Godot Engine's Android port.
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
// CAS Gradle Plugin
id 'com.cleveradssolutions.gradle-plugin' version "4.6.5"
}
cas {
includeOptimalAds = true
includeTenjinSDK = true
useAdvertisingId = true
}Note that you don't need to specify casId here due to it usually being your package name (e.g. "com.yourstudio.yourgame") and it is specified by Godot Android build as applicationId which CAS Gradle plugin fetches on its own.
This plugin's configuration file GodotCas.gdap contains all adapters out of the box (excluding beta and cross-promo). Usually it's not desirable because your app may be not making use of all of them and having unnecessary adapters present will increase build size. Feel free to add/remove adapters and their repositories according to your needs.
Make sure to check out this list of adapters and also this guide page from CAS official wiki.
Also check adapters-list.txt for precise dependencies and repositories for Optimal and Families presets.
com.google.android.gms:play-services-ads-identifier dependency is required if you want to use AD ID (which is usually the case).
com.tenjin:android-sdk dependency would be necessary if you want to enable automatic revenue reporting for Tenjin. See this wiki page for more details.
Wrapper script GodotCas.gd has initialize() method which you are supposed to edit and then call in runtime. There are some methods that tweak initialization options for the SDK, and you have to call them before initializeCAS() is executed. Each method in the wrapper is documented by a comment, so make sure to inspect it.
All methods below should come before initializeCAS() if called.
# Mandatory. Sets CAS ID (usually your app package or bundle ID).
# Not setting the ID before initializeCas() will lead to plugin crash.
setCasId(id:String) -> void
# CAS built in consent manager is enabled by default, but you can disable it.
# It's still recommended to use their consent manager, so better leave it be.
setUseBuiltInConsentManager(enabled:bool) -> void
# If enabled, turns test ads mode on.
setTestAdMode(enabled:bool) -> void
# See https://docs.page/cleveradssolutions/docs/Android/Impression-Level-Data#automatic-collect-ad-revenue
# If using this, make sure you have TenjinSDK dependency in GodotCas.gdap configuration.
setTenjinKey(key:String) -> void
# See https://docs.page/cleveradssolutions/docs/Android/Additional-Meta-AudienceNetwork-steps
setFacebookLDU(enabled:bool) -> void# Debug Mode displays debug info with log tag "CAS". Disabled by default for performance.
setDebugMode(enabled:bool) -> void
# Adds testing device ID.
# see https://docs.page/cleveradssolutions/docs/Android/Enabling-test-ads#enable-test-devices
addTestDeviceId(id:String) -> voidCAS SDK provides automated consent screen workflow with their own consent screen.
# Shows consent manager if it is required (e.g. based on user's geo).
showConsentManagerIfRequired() -> void
# Force-shows the consent manager.
showConsentManager() -> voidIn case you use your own consent screen, consent status can be set via these methods:
enum CONSENT_STATUS {
UNDEFINED = 0
ACCEPTED = 1
DENIED = 2
}
# Use this if using your own consent manager. See CONSENT_STATUS enum.
setConsentStatus(status:int) -> void
enum CCPA_STATUS {
UNDEFINED = 0
OPT_OUT_SALE = 1
OPT_IN_SALE = 2
}
# Use this if using your own consent manager. See CCPA_STATUS enum.
setCcpaStatus(status:int) -> voidYou can also test consent screen behavior to make sure everything works as intended.
# Returns possible consent flow statuses as String : int dict for lookup.
getPossibleConsentFlowStatuses() -> Dictionary
# Returns possible debug geographies as String : int dict for lookup.
getPossibleDebugGeographies() -> Dictionary
# Sets debug geography for consent manager testing.
# Will have no effect unless force testing is enabled for consent manager.
setConsentDebugGeography(geography:int) -> void
# Enabled forced testing for consent manager.
setConsentForceTesting(enabled:bool) -> voidDevelopers who have knowledge of specific individuals as being COPPA-applicable should make use of the API discussed below to inform CAS and all downstream consumers of this information.
enum AUDIENCE {
UNDEFINED = 0
CHILDRED = 1
NOT_CHILDREN = 2
}
# Specify what audience is the user in. See AUDIENCE enum.
setTaggedAudience(audienceType:int) -> void
This plugin supports Interstitial, Rewarded, Banner and App Open ad types. Native ad type is not currently implemented due to having extremely few use cases in games.
Every ad-type has a corresponding initialization function: initializeInterstitial(), initializeRewarded() and so on. Make sure you call such a function before calling other methods relevant to an ad type.
# Initializes the CASInterstitial object in the plugin and creates callbacks.
initializeInterstitial() -> void
# Loads the interstitial ad.
loadInterstitial() -> void
# Returns false is ad is not loaded yet or the CASInterstitial object hasn't been initialized.
isInterstitialLoaded() -> bool
# Shows the interstitial ad.
showInterstitial() -> void
# Destroys the interstitial ad instance.
destroyInterstitial() -> void
# Sets autoloading for interstitials, disabled by default.
setAutoloadInterstitial(enabled:bool) -> void
# Sets an interval between interstitial ad shows prohibiting ads from showing during it.
setMinIntervalInterstitial(seconds:int) -> void
# Restarts the interval specified by setMinIntervalInterstitial().
restartIntervalInterstitial() -> void# Initializes the CASRewarded object in the plugin and creates callbacks.
initializeRewarded() -> void
# Loads the rewarded ad.
loadRewarded() -> void
# Returns false is ad is not loaded yet or the CASRewarded object hasn't been initialized.
isRewardedLoaded() -> bool
# Shows the rewarded ad.
showRewarded() -> void
# Destroys the rewarded ad instance.
destroyRewarded() -> void
# Sets autoloading for rewarded, disabled by default.
setAutoloadRewarded(enabled:bool) -> void
# Enabled by default. Sets if an interstitial ad should be displayed in case there is no-fill for rewarded.
setRewardedExtraFillInterstitial(enabled:bool) -> void# Initializes CASBannerView. See BANNER_SIZE enum.
# Also see https://docs.page/cleveradssolutions/docs/Android/Banner-Ads#create-ad-view
initializeBanner(bannerSize:int) -> void
# Initializes CASBannerView with adaptive size.
# See https://docs.page/cleveradssolutions/docs/Android/Banner-Ads#get-the-ad-size
initializeAdaptiveBanner(maxWidthDpi:int) -> void
# Loads the banner ad.
loadBanner() -> void
# Returns false if ad is not loaded yet or the CASBannerView object hasn't been initialized.
isBannerLoaded() -> bool
# Sets banner visibility.
setBannerVisible(isVisible:bool) -> void
# Destroys the banner ad instance.
destroyBanner() -> void
# Sets autoloading for banner. Enabled by default.
setAutoloadBanner(enabled:bool) -> void
# Sets banner refresh interval. Should be longer than 10 seconds, 30 considered optimal (default).
setBannerRefreshInterval(seconds:int) -> void
# Disables ad refresh for banner.
disableBannerAdRefresh() -> void
# Sets banner position in device's actual viewport.
setBannerPosition(posX:float, posY:float) -> void
# Returns banner width in device's actual viewport.
getBannerWidth() -> int
# Returns banner height in device's actual viewport.
getBannerHeight() -> int# Initializes the CASAppOpen object in the plugin and creates callbacks.
initializeAppOpenAd() -> void
# Loads the AppOpen ad.
loadAppOpenAd() -> void
# Returns false if ad is not loaded yet or the CASAppOpen object hasn't been initialized.
isAppOpenAdLoaded() -> bool
# Shows the AppOpen ad.
showAppOpenAd() -> void
# Destroys the AppOpen ad instance.
destroyAppOpenAd() -> void
# Sets autoloading for AppOpen ad, disabled by default.
setAutoloadAppOpenAd(enabled:bool) -> void
# Sets autoshowing for AppOpen ad, disabled by default.
setAutoshowAppOpenAd(enabled:bool) -> voidYou can log in-app purchase events to Tenjin with this plugin. Just make sure to obtain the necessary purchase data from Godot Google Play Billing Library Plugin.
You will probably be calling this from inside purchases_updated signal of Billing Plugin, but I strongly advise you call logging with some delay (like 2 seconds). Reason being, TenjinSDK might be suspended in this particular moment and there's a possibility that your logging attempt won't go through.
Make sure that Tenjin dependency is present in plugins GDAP file.
More info on data required can be found in Tenjin docs
# Data for arguments is supposed to be obtained from Google Billing Library plugin for Godot.
# CAS should be initialized with Tenjin key for this to work (might cause crash otherwise).
logTenjinPurchaseEvent(sku:String, currencyCode:String, quantity:int, price:float, originalJson:String, signature:String) -> void# See https://docs.page/cleveradssolutions/docs/Android/Targeting-options#user-id
setUserID(userID:String) -> void
# See https://docs.page/cleveradssolutions/docs/Android/Targeting-options#user-age
setUserAge(age:int) -> void
enum GENDER {
UNKNOWN = 0,
MALE = 1,
FEMALE = 2
}
# See GENDER enum for the argument.
# See https://docs.page/cleveradssolutions/docs/Android/Targeting-options#user-gender
setUserGender(gender:int) -> void
# See https://docs.page/cleveradssolutions/docs/Android/Targeting-options#user-location-auto-collection
setUserLocationAutocollection(enabled:bool) -> void
# See https://docs.page/cleveradssolutions/docs/Android/Targeting-options#app-keywords
setUserAppKeywords(keywords:PoolStringArray) -> void
# See https://docs.page/cleveradssolutions/docs/Android/Targeting-options#app-content-url
setAppContentUrl(contentUrl:String) -> voidCAS SDK can output integration status to logcat, displaying what adapters are integrated or not.
# Call Integration Helper and check current integration in logcat. LOG TAG: CASIntegrationHelper
validateIntegration() -> voidYou can check if user has WIFI/Mobile traffic enabled on their device. This DOES NOT guarantee a working internet connection and only checks the status of WIFI and mobile traffic enabled in Android. For example, if user is connected to a WIFI but this WIFI doesn't give access to Internet, this will still return true.
# Returns true if the device has WIFI or Mobile traffic enabled. This doesn't guarantee real internet connection.
isWifiOrMobileInternetEnabled() -> bool