Аналитика в игре на Godot: подключаем MyTracker

108e1f982f9c173c2ecbf979b3daa3a4.png

Привет! Я Артем Ковардин, руководитель команды Push Service в RuStore. В этой статье мы с вами рассмотрим, как подключить MyTracker для мобильной игры на Godot. 

Godot — замечательный движок для игр, но под него достаточно мало готовых плагинов. Поэтому часто разработчику нужно самостоятельно создавать все необходимые плагины: для аналитики, рекламы, подписок и так далее. Начнем с того, что помогает нам качественно развиваться — аналитика.

Прежде всего, аналитика помогает разработчику зарабатывать на своих играх. Она нужна любому приложению: без аналитики не получится закупить трафик, непонятно, сколько времени пользователь проводит в приложении и сколько удалось заработать с каждого источника. 

В этой статье мы будем работать с сервисом аналитики MyTracker. Это позволит закупать рекламу на площадках VK. Разберемся, как подключить сервис, разработать плагин для аналитики и подключить его в игру.

Добавление игры в MyTracker

Добавляем игру в своём аккаунте MyTracker. Начинаем с указания ссылки на приложение.

c8b2a33c0c64ea4401b77e5be9534d91.png

Создаём проект и указываем валюту RUB.

e729a0d9d02fb2ff56c9cb817cbe4c25.png

Сохраняем настройки и попадаем на страницу с инструкцией по подключению SDK.

97cb57527a32553c08273af8c94a7170.png

Все готово, идём создавать плагин и подключать его в нашу игру.

Первым делом создаём Android проект. Никаких хитростей тут нет, все делаем как с обычным приложением на Android.

После создания проекта добавляем новый модуль с названием my-tracker. В нём пропишем всю логику плагина, которая будет доступна в нашей игре. Но чтобы все заработало, нужно добавить специальную библиотеку для разработки плагинов под Android. Эту библиотеку можно найти на странице с загрузками Godot. Выбираем пункт AAR library for Android и загружаем .aar библиотеку в папку godot-lib.

Чтобы библиотека из godot-lib стала доступна в проекте, создаём скрипт gradle.

configurations.maybeCreate("default")
artifacts.add("default", file('godot-lib.4.0.2.stable.template_release.aar'))

Все модули перечисляем в settings.gradle.

rootProject.name = "rustore-my-tracker"
include ':app'
include ':godot-lib'
include ':my-tracker'

Зависимости

Теперь нужно подключить библиотеку MyTracker. Посмотреть актуальную версию можно в документации MyTracker. На момент написания статьи актуальной была версия 'com.my.tracker:mytracker-sdk:3.0.+'. Подключать библиотеку будем по-хитрому.

Нужно создать специальный файл MyTracker.gdap, в котором будет вся необходимая информация о плагине.

[config]

name="MyTracker"
binary_type="local"
binary="my-tracker-release.aar"

[dependencies]

remote=["com.my.tracker:mytracker-sdk:3.0.+"]

В параметре name этого файла указываем имя плагина, в параметре binary_typelocal, а в binary — название собранной .aar библиотеки. Если указать binary_type=remote, в параметре binary нужно добавить ссылку на .aar.

Самое интересное начинается в секции dependencies. Зависимости можно указать local или remote. В нашем случае указывается только одна remote зависимость. При необходимости можно указать список сторонних репозиториев через параметр custom_maven_repos=[], но для нашего плагина это не нужно. Все эти зависимости будут использоваться при сборке игры на Godot. Узнать больше подробностей про параметры плагина можно в документации Godot.

А теперь время магии gradle. Напишем немного кода, чтобы не копировать руками зависимость из my-tracker/MyTracker.gdap в my-tracker/build.gradle.

dependencies {
     File gdap = new File("my-tracker/MyTracker.gdap")
     def match = gdap.text =~ /(?<=remote=)[^;]+/
 
     def remote = Eval.me(match[0])
 
     for(item in remote){
         println "implementing $item"
         implementation item
    }

    compileOnly project(':godot-lib')
}

Этот код честно подсмотрен в плагине для AdMob — неплохой пример для изучения, но у нас будет лучше.

В коде выше мы открываем файл MyTracker.gdap, парсим его, находим все пакеты, указанные в параметре remote, и подключаем их как implementation. Теперь, если нужно поднять версию библиотеки Android, достаточно внести изменения только в один файл. Конечно, отдельно нужно будет указать кастомные репозитории, но даже так жизнь становится проще.

Все зависимости подключены и можно приступать к написанию скриптом. Давайте создадим файл для нашего плагина, назовём его MyTracker.kt. Итоговая структура проекта получается такой:

- app/
- godot-lib/
    - build.gradle
    - godot-lib.4.0.2.stable.template_release.aar
- my-tracker/
    - src/
    - build.gradle
    - MyTracker.gdap
- build.gradle
- settings.gradle

Реализация

Начнём с создания класса нашего плагина в файле MyTracker.kt:

package ru.rustore.mytracker
 
 import org.godotengine.godot.Godot
 import org.godotengine.godot.plugin.GodotPlugin
 
 class MyTracker(godot: Godot?) : GodotPlugin(godot) {
     override fun getPluginName(): String {
         return "MyTracker"
     }
}

Пока все просто. Наследуемся от базового класса GodotPlugin и реализуем один метод getPluginName(), который, ожидаемо, возвращает название плагина.

Чтобы игра смогла найти этот класс и загрузить плагин, необходимо добавить нужную информацию в файл AndroidManifest.xml модуля my-tracker:



    
        
    

Теперь нужно реализовать инициализацию трекера. По-хорошему, инициализировать трекер нужно непосредственно при создании приложения в методе Application.onCreate(). Но в MyTracker можно инициализировать его вручную с использованием метода trackLaunchManually():

package ru.rustore.mytracker
 
 import com.my.tracker.MyTracker as Tracker
 import org.godotengine.godot.Godot
 import org.godotengine.godot.plugin.GodotPlugin
 import org.godotengine.godot.plugin.UsedByGodot
 
 class MyTracker(godot: Godot?) : GodotPlugin(godot) {
     override fun getPluginName(): String {
        return "MyTracker"
    }

    @UsedByGodot
    fun init(key: String) {
        if (godot == null) {
            return
        }

        Tracker.initTracker(key, godot.requireActivity().application)
        Tracker.trackLaunchManually(godot.requireActivity())
    }
}

Сначала добавляем метод init() и помечаем его @UsedByGodot. Как несложно догадаться, этот метод будет доступен из Godot.

Теперь нужно добавить возможность конфигурировать трекер из Godot. Для этого добавляем пачку методов, которые проксируют вызовы методов класса MyTrackerConfig.

@UsedByGodot
 fun setTrackingLaunchEnabled(trackingLaunchEnabled: Boolean) {
     Tracker.getTrackerConfig().setTrackingLaunchEnabled(trackingLaunchEnabled)
 }
 
 @UsedByGodot
 fun setLaunchTimeout(seconds: Int) {
     Tracker.getTrackerConfig().setLaunchTimeout(seconds)
 }

@UsedByGodot
fun setBufferingPeriod(seconds: Int) {
    Tracker.getTrackerConfig().setBufferingPeriod(seconds)
}

@UsedByGodot
fun setForcingPeriod(seconds: Int) {
    Tracker.getTrackerConfig().setForcingPeriod(seconds)
}

@UsedByGodot
fun setAutotrackingPurchaseEnabled(autotrackingPurchaseEnabled: Boolean) {
    Tracker.getTrackerConfig().setAutotrackingPurchaseEnabled(autotrackingPurchaseEnabled)
}

@UsedByGodot
fun setTrackingPreinstallEnabled(trackingPreinstallEnabled: Boolean) {
    Tracker.getTrackerConfig().setTrackingPreinstallEnabled(trackingPreinstallEnabled)
}

@UsedByGodot
fun setApkPreinstallParams(apkPreinstallParams: String) {
    Tracker.getTrackerConfig().setApkPreinstallParams(apkPreinstallParams)
}

Отлично, теперь из Godot можно настраивать трекер. Но нужно добавить возможность указывать параметры.

@UsedByGodot
 fun setCustomParam(key: String, value: String) {
     Tracker.getTrackerParams().setCustomParam(key, value)
 }
 
 @UsedByGodot
 fun setEmail(email: String) {
     Tracker.getTrackerParams().setEmail(email)
 }

@UsedByGodot
fun setCustomUserId(id: String) {
    Tracker.getTrackerParams().setCustomUserId(id)
}

@UsedByGodot
fun setAge(age: Int) {
    Tracker.getTrackerParams().setAge(age)
}

@UsedByGodot
fun setPhone(phone: String) {
    Tracker.getTrackerParams().setPhone(phone)
}

@UsedByGodot
fun setLang(lang: String) {
    Tracker.getTrackerParams().setLang(lang)
}

На самом деле сеттеров ещё больше, но я использовал только самые популярные.

Осталось добавить последний и самый важный набор методов для трекания событий.

@UsedByGodot
 fun trackInviteEvent(params: Dictionary) {
     Tracker.trackInviteEvent(params.map { e -> e.key to e.value.toString() }.toMap())
 }
 
 @UsedByGodot
 fun trackLevelEvent(level: Int, params: Dictionary) {
     Tracker.trackLevelEvent(level, params.map { e -> e.key to e.value.toString() }.toMap())
 }

@UsedByGodot
fun trackEvent(name: String, params: Dictionary) {
    Tracker.trackEvent(name, params.map { e -> e.key to e.value.toString() }.toMap())
}

Обратите внимание на тип переменной params. Мы не можем просто передать из Godot тип Map. Поддерживаются только: void, boolean, int, float, java.lang.String, org.godotengine.godot.Dictionary, int[], byte[], float[], java.lang.String[]. Поэтому нужно конвертировать org.godotengine.godot.Dictionary в тип Map.

С помощью метода params.map { e -> e.key to e.value.toString() }.toMap() мы пробегаем по всем значениям Map и конвертируем их в строку String, а потом результат отдаётся в виде Map. Надеюсь, это сработает.

Ещё один важный метод — учёт покупок. Он создаётся довольно просто:

fun trackPurchaseEvent(
     sku: String,
     purchase: String,
     signature: String,
     params: Dictionary
 ) {
     Tracker.trackPurchaseEvent(
         JSONObject(sku),
         JSONObject(purchase),
        signature,
        params.map { e -> e.key to e.value.toString() }.toMap()
    )
}

Чтобы учитывать покупки через него, нужно отключить автоматический трекинг покупок, используя метод setAutotrackingPurchaseEnabled(false).

По умолчанию SDK MyTracker отправляет данные на сервер раз в 15 минут. Но некоторые события важно отправить как можно раньше, и для этого есть метод flush().

@UsedByGodot
fun flush() {
    Tracker.flush()
}

Все нужные методы добавлены, собираем наш плагин и тестируем в реальной игре.

Сейчас добавлены только базовые методы, которые позволяют интегрировать и использовать SDK MyTracker в игре. О других возможностях вы можете почитать в документации MyTracker.

Сборка и подключение

Собираем всё командой ./gradlew build, как обычный модуль Android. Остаётся только скопировать файлы my-tracker-release.aar и MyTracker.gdap в папку res://android/plugins.

В вашей игре должен быть установлен Android Build Template для правильной работы плагина. Если Android Build Template установлен корректно, после добавления плагина, он отобразится в списке на экране настройки экспорта:

742418ed2141c23506d106b43453bbb0.png

Это значит, что плагин доступен в коде самой игры.

Использование

Все начинается с метода _ready() в скрипте Game.gd. Нужно проверить доступность плагина методом Engine.has_singleton().

func _ready():
    if Engine.has_singleton("MyTracker"):
        var tracker = Engine.get_singleton("MyTracker")

tracker — экземпляр нашего плагина. Мы можем вызывать методы, которые определили в класса плагина.

func _ready():
    if Engine.has_singleton("MyTracker"):
        var tracker = Engine.get_singleton("MyTracker")
        
        tracker.setDebugMode(true)
        tracker.init("xxxxxxxxxxx")

xxxxxxxxxxx — SDK-ключ, который мы получили при создании приложения в настройках MyTracker. Метод setDebugMode(true) позволяет увидеть работу MyTracker в logcat приложения.

527a9dc92d892a42eafa255a330e7da5.png

Залогируем событие завершения игры и событие рестарта. Для этого немного поправим код нашей игры.

func _on_collided():
 	tracker.trackEvent("finish", {
 		"points": "%d" % score,
 	})
 	restart.show()
 	hero.active = false
 	hero.boom()
 	play = false
 	for ch in get_children():
		if ch.is_in_group("Enemy"):
			remove_child(ch)

func _on_restart_pressed():
	tracker.trackEvent("restart", {
		"points": "%d" % score,
	})
	get_tree().reload_current_scene()

Эти события можно будет смотреть в отчётах MyTracker.

Убираем вызов tracker.setDebugMode(true), собираем игру и публикуем её новую версию.

Исходники

Исходники плагина для MyTracker доступны в GitFlic.

Заключение

В этой статье мы рассмотрели шаги подключения сервиса MyTracker к игре на Godot. Этот сервис поможет вам обезличенно анализировать поведение игроков, собирать статистику и закупать рекламу.

© Habrahabr.ru