Skip to main content

Game Role API

The Game Role API tells the SDK which server, character, and level the player is currently on — used to enrich analytics and IAP tracking with player context.

The One Rule​

There is exactly one call to make: setGameRole(), any time the player's server, character, or level changes. It's cheap and safe to call often — there's no separate API for "on level up" or "on character switch," it's always the same call, wired to whatever hook in your game already notices player state changing.

Call it from every one of these trigger points:

  • Right after login, once you know the player's starting server/character
  • After creating a new character
  • Whenever the player switches character or server — this fires af_sdk_switch_role automatically, no extra step needed
  • Whenever the player levels up — easy to forget since it's not a "switch," but skipping it means level silently drifts stale in analytics with no error to flag it
Kotlin
// Call this from wherever your game already tracks these values changing —
// login, character creation, server switch, level up all funnel through here.
fun reportGameRole(player: Player) {
OEGAuthCore.setGameRole(
serverId = player.serverId,
serverName = player.serverName,
roleId = player.characterId,
roleName = player.characterName,
level = player.level
)
}
Java
public void reportGameRole(Player player) {
OEGAuthCore.INSTANCE.setGameRole(
player.getServerId(), player.getServerName(),
player.getCharacterId(), player.getCharacterName(), player.getLevel()
);
}

When the player instead leaves to a character/server-select screen with no role picked yet — a real gap, not a direct switch — call logoutGameRole() first so no stale role backs analytics/purchases in the meantime (see below).

API Reference​

setGameRole()​

Kotlin
import vn.oeg.sdk.v2.core.auth.OEGAuthCore

OEGAuthCore.setGameRole(
serverId: String,
serverName: String? = null,
roleId: String,
roleName: String? = null,
level: Int = 0
)
Java
import vn.oeg.sdk.v2.core.auth.OEGAuthCore;

// All parameters required from Java — use null for optional String, 0 for default level
OEGAuthCore.INSTANCE.setGameRole(serverId, serverName, roleId, roleName, level);

Parameters:

ParameterTypeRequiredDescription
serverIdString✅ YesGame server identifier (e.g., "server_01", "asia_1")
serverNameString?❌ NoHuman-readable server name (e.g., "Asia Server 1")
roleIdString✅ YesCharacter/role unique identifier
roleNameString?❌ NoCharacter/role display name (e.g., "DragonSlayer")
levelInt❌ NoCharacter level (default: 0)

Returns: Nothing (void)

Storage: In-memory only (cleared on logout)

Analytics: If a role was already active and serverId/roleId actually change, fires af_sdk_switch_role (old + new server/role). The very first call after login is treated as an initial pick, not a switch, and does not fire it.

logoutGameRole()​

Clears the active character/server context without logging the account out — call when the player returns to a server/character-select screen, before the next setGameRole() call for the newly chosen one. Optional: calling setGameRole() again directly for the new role is enough for a plain switch: use logoutGameRole() when there's a real gap (e.g. player is back at the character-select screen with no role picked yet).

The SDK only clears its own state and fires the analytics event — it does not navigate anywhere. callback fires once that's done; use it to move the game to its own switch-server screen.

Kotlin
import vn.oeg.sdk.v2.core.auth.OEGAuthCore

OEGAuthCore.logoutGameRole {
// Game role cleared — navigate to your own switch-server screen here
navigateToServerSelect()
}
Java
import vn.oeg.sdk.v2.core.auth.OEGAuthCore;

OEGAuthCore.INSTANCE.logoutGameRole(() -> {
// Game role cleared — navigate to your own switch-server screen here
navigateToServerSelect();
});

Returns: Nothing (void) — reports completion via callback

Analytics: Fires af_sdk_logout_game_role (with the role that was just cleared) — but only when a role was actually active. Calling it when no role is set is a safe no-op and does not fire the event.

How It's Used​

The SDK uses game role data in the following ways:

1. Analytics Events​

Role information is automatically included in analytics events:

  • af_sdk_recharge (IAP events): Includes role_id, role_name, server_id
  • af_logout: Includes server_id
  • af_sdk_switch_role: Fired by setGameRole() when it replaces an already-active role with a different server/role. Includes old_server_id, old_role_id, server_id (new), role_id (new)
  • af_sdk_logout_game_role: Fired by logoutGameRole() when it clears an active role. Includes server_id, role_id (the role that was cleared)
  • Custom events: Available for game-specific tracking

These af_-prefixed names are what AppsFlyer receives. Adjust receives a different, per-game opaque event token configured in the CMS for the same logical event — not these literal strings.

2. IAP Tracking​

When a player makes an in-app purchase, the SDK automatically includes role context:

Kotlin
// Game calls IAP
OEGPayment.purchaseAndVerify(productId, gameData) { result ->
// SDK automatically tracks af_sdk_recharge event with:
// - role_id from gameData (primary); falls back to setGameRole() if gameData field is empty
// - role_name from gameData (primary); falls back to setGameRole() if empty
// - server_id from gameData (primary); falls back to setGameRole() if empty
}
Java
OEGPayment.INSTANCE.purchaseAndVerify(productId, gameData, (purchaseResult, result) -> {
// SDK automatically tracks af_sdk_recharge event with role data from gameData (primary)
});

3. Priority and Fallback Behavior​

For IAP analytics, the SDK uses GameData as the primary source (it is always present at purchase time). setGameRole() data is used as a fallback when a GameData field is empty.

FieldPrimaryFallback
role_idgameData.characterIdgameRole.roleId
role_namegameData.characterNamegameRole.roleName
server_idgameData.serverIdgameRole.serverId

For non-IAP events (e.g. af_logout), the SDK uses setGameRole() data directly.

Best practice: Always populate GameData fields when calling purchaseAndVerify() for accurate IAP tracking.

Data Lifecycle​

Storage​

  • Location: In-memory only (not persisted to disk)
  • Scope: Current session only
  • Access: Internal to SDK (not exposed to game)

Clearing​

Call logoutGameRole() explicitly when the player returns to a server/character-select screen (fires af_sdk_logout_game_role). Game role data is also automatically cleared — silently, no event — in these scenarios:

  1. User logs out:
Kotlin
OEGAuth.logout() // Clears game role automatically
Java
OEGAuth.INSTANCE.logout(); // Clears game role automatically
  1. Session expires:

    • SDK receives 401 from backend
    • Game role cleared during session cleanup
  2. Force logout (maintenance):

    • SDK force logs out user
    • Game role cleared

Persistence​

Game role data is NOT persisted across app restarts. You must call setGameRole() again after:

  • App restart
  • User logs in again
  • Session restoration

Reading Game Role (Internal)​

The game role data is stored internally and used by the SDK. Games typically don't need to read it back, but if needed:

Kotlin
val gameRole = OEGAuthCore.gameRole

if (gameRole != null) {
val serverId = gameRole.serverId
val serverName = gameRole.serverName
val roleId = gameRole.roleId
val roleName = gameRole.roleName
val level = gameRole.level
}
Java
OEGGameRole gameRole = OEGAuthCore.INSTANCE.getGameRole();

if (gameRole != null) {
String serverId = gameRole.getServerId();
String serverName = gameRole.getServerName();
String roleId = gameRole.getRoleId();
String roleName = gameRole.getRoleName();
int level = gameRole.getLevel();
}

Note: This is read-only. Use setGameRole() to update.

Best Practices​

✅ Do​

  • Wire setGameRole() into whichever single place your game already tracks server/character/level — don't treat login, character switch, and level-up as separate integrations
  • Include level every time, not just at login — it's the field most likely to go stale if treated as optional
  • Use meaningful IDs (e.g., "server_01", not "1")
  • Include optional fields when available (improves analytics)

❌ Don't​

  • Don't call before login completes
  • Don't use sensitive data in role names
  • Don't skip re-calling it on level-up because it "isn't a switch" — same call, just a changed value
  • Don't rely on persistence across sessions

Troubleshooting​

Role data not appearing in analytics​

Problem: IAP events show empty role fields

Solutions:

  1. Verify setGameRole() is called after login
  2. Check that it's called before IAP purchase
  3. Ensure parameters are non-empty strings
  4. Check logs for any SDK errors

Role data cleared unexpectedly​

Problem: Role data disappears during session

Cause: User logged out or session expired

Solution: Re-call setGameRole() after re-login

Multiple characters per account​

Problem: Game supports multiple characters, which one to track?

Solution: Call setGameRole() for the currently active character. Update when player switches characters.

Backend behavior: every server tracks each character separately — a second roleId on the same serverId does not replace the first, both persist. Whichever one setGameRole() was called for most recently is what Console's player roster marks as that server's current character. If your game only calls setGameRole() when the player enters a server (not on every character switch within it), Console's "current" marker goes stale — it still shows whichever character was picked at login, not the one actually being played. Analytics are unaffected either way: af_sdk_switch_role / sdk_switch_role only fires from an explicit setGameRole() call.