Send events
Game telemetry is not available on AGS Shared Cloud tier.
Overview
The Game Telemetry service, you can track and log players' actions within the game by sending an event. This event will be tracked to the game's streaming pipeline. To track those actions a Player Session is required, so you must enable your players to create an account in your game before you can use this feature.
Preparation before sending events
By default, telemetry events will be sent to a game's streaming pipeline as a batch after a set amount of time. This amount of time should be configured before telemetry events can be sent. Any events that should be sent immediately should also be added to the immediate event list. Here is an example of how to configure your telemetry events.
- Unreal
- Unity
TArray < FString > ImmediateEventList = {
"ITEM_SOURCE",
"ITEM_SINK",
"SPECIALISED_ABILITY"
};
FTimespan Interval = FTimespan::FromSeconds(30);
// set for game client
FRegistry::GameTelemetry.SetImmediateEventList(ImmediateEventList);
FRegistry::GameTelemetry.SetBatchFrequency(Interval);
// set for game server
FRegistry::ServerGameTelemetry.SetImmediateEventList(ImmediateEventList);
FRegistry::ServerGameTelemetry.SetBatchFrequency(Interval);
List<string> eventList = new List<string>();
eventList.Add("ITEM_SOURCE");
eventList.Add("SPECIALISED_ABILITY");
System.TimeSpan interval = System.TimeSpan.FromSeconds(30.0f);
// For Game Client
AccelByte.Core.AccelByteSDK.GetClientRegistry().GetApi().GetGameTelemetry().SetImmediateEventList(eventList);
AccelByte.Core.AccelByteSDK.GetClientRegistry().GetApi().GetGameTelemetry().SetBatchFrequency(interval);
// For Game Server
AccelByte.Core.AccelByteSDK.GetServerRegistry().GetApi().GetGameTelemetry().SetImmediateEventList(eventList);
AccelByte.Core.AccelByteSDK.GetServerRegistry().GetApi().GetGameTelemetry().SetBatchFrequency(interval);
Send events using the client SDKs
The following function signature can also be used to send an event. The returned data will be displayed in your data warehouse, where you'll be able to customize its visualization.
- Unreal
- Unity
FJsonObject Payload;
Payload.SetStringField("someString", "someString");
Payload.SetNumberField("someInt", i);
Payload.SetBoolField("someBool", true);
FAccelByteModelsTelemetryBody TelemetryBody;
TelemetryBody.EventName = "ExampleEvent";
TelemetryBody.EventNamespace = "GameNamespace";
TelemetryBody.Payload = MakeShared < FJsonObject > (Payload);
bool bTelemetryEventSent = false;
FRegistry::GameTelemetry.Send(
TelemetryBody,
FVoidHandler::CreateLambda([ & ]() {
UE_LOG(LogTemp, Log, TEXT(" Success"));
}),
FErrorHandler::CreateLambda([](int32 ErrorCode,
const FString & ErrorMessage) {
UE_LOG(LogTemp, Fatal, TEXT(" Error. Code: %d, Reason: %s"), ErrorCode, * ErrorMessage);
})
);
var telemetryBody = new AccelByte.Models.TelemetryBody
{
EventName = "SomeEventName",
EventNamespace = "SomeEventNamespace",
Payload = new { someString = "", someInt = 20, someBool = false }
};
// For client
AccelByteSDK.GetClientRegistry().GetApi().GetGameTelemetry().Send(telemetryBody, result =>
{
if (result.IsError)
{
// Do something if Send Event has an error
Debug.Log($"Error Send, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}
// Do something if Send Event has been successful
});
// For server
AccelByteSDK.GetServerRegistry().GetApi().GetGameTelemetry().Send(telemetryBody, result =>
{
if (result.IsError)
{
// Do something if Send Event has an error
Debug.Log($"Error Send, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}
// Do something if Send Event has been successful
});
To immediately send events in the batch without waiting for batch interval, use SendTelemetryBatch
.
// For client
AccelByteSDK.GetClientRegistry().GetApi().GetGameTelemetry().SendTelemetryBatch(result =>
{
if (result.IsError)
{
// Do something if Send Event has an error
Debug.Log($"Error Send, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}
// Do something if Send Event has been successful
});
// For server
AccelByteSDK.GetServerRegistry().GetApi().GetGameTelemetry().SendTelemetryBatch(result =>
{
if (result.IsError)
{
// Do something if Send Event has an error
Debug.Log($"Error Send, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}
// Do something if Send Event has been successful
});
Send events using Extend SDKs
The following function signature can also be used to send an event. The returned data will be displayed in your data warehouse, where you'll be able to customize its visualization.
- Go Extend SDK
- Python Extend SDK
- Java Extend SDK
- C# Extend SDK
gametelemetryOperationsService := &gametelemetry.GametelemetryOperationsService{
Client: factory.NewGametelemetryClient(&repository.ConfigRepositoryImpl{}),
TokenRepository: &repository.TokenRepositoryImpl{},
}
eventName := "SomeEventName"
eventNamespace := "SomeEventNamespace"
item := gametelemetryclientmodels.TelemetryBody {
EventName: &eventName,
EventNamespace: &eventNamespace,
}
body := []*gametelemetryclientmodels.TelemetryBody {
&item,
}
input := &gametelemetry_operations.ProtectedSaveEventsGameTelemetryV1ProtectedEventsPostParams{
Body: body
}
err := gametelemetryOperationsService.ProtectedSaveEventsGameTelemetryV1ProtectedEventsPostShort(input)
import accelbyte_py_sdk.api.gametelemetry as gametelemetry_service
import accelbyte_py_sdk.api.gametelemetry.models as gametelemetry_models
result, error = gametelemetry_service.protected_save_events_game_telemetry_v1_protected_events_post(
body=[
gametelemetry_models.TelemetryBody()
.with_event_name("ExampleEvent")
.with_event_namespace("GameNamespace")
.with_payload(
{
"someString": "someString",
"someInt": 1,
"someBool": True,
}
)
]
)
if error:
exit(error)
GametelemetryOperations gametelemetryOperationsWrapper = new GametelemetryOperations(sdk);
String additionalKey = "Your additional key";
String userId = "<user-id>";
List<BulkStatOperationResult> response;
try {
List<TelemetryBody> reqBody = List.of(
TelemetryBody.builder()
.eventName("SomeEventName")
.eventNamespace("SomeEventNamespace")
.payload(
Map.of(
"someString", "",
"someInt", 20,
"someBool", false
)).build()
);
gametelemetryOperationsWrapper.protectedSaveEventsGameTelemetryV1ProtectedEventsPost(ProtectedSaveEventsGameTelemetryV1ProtectedEventsPost.builder()
.body(reqBody)
.build());
} catch (Exception e) {
// Do something when failed
return;
}
sdk.Gametelemetry.GametelemetryOperations.ProtectedSaveEventsGameTelemetryV1ProtectedEventsPostOp
.Execute(new List<TelemetryBody>()
{
new TelemetryBody()
{
EventName = "SomeEventName",
EventNamespace = "SomeEventNamespace",
Payload = new Dictionary<string, object>()
{
{ "someString", "" },
{ "someInt", 20 },
{ "someBool", false }
}
}
});
Send events using APIs
Use the Protected Save Events: POST - /game-telemetry/v1/protected/events
endpoint. Event message size is limited to 1 MB.
Fill in the Request Body.
- Input the EventNamespace with the game namespace.
- Input the EventName with the name of the event. For example "player_killed" or "mission_accomplished".
- Input the Payload with an arbitrary JSON of the event.
Here are some examples of the payload for different use cases.
If you want to track player logins and logouts, you can use the following reference for your request body.
Login:
{
"EventName" : "player_logged_in",
"EventNamespace" : "abshooter", // Game Namespace
"Payload": {
"GameSessionId" : "generated after the game client is executed",
"UserId" : "could be obtained from player's credential information",
"LoginSessionId" : "generated after the player has been logged in",
"LoginType" : "[USERNAME, LAUNCHER, STEAM, etc..]",
"GameVersion" : "our game release version",
"SDKVersion" : "version of AccelByte SDK in the game's project",
"DSTargetVersion" : "version of dedicated server image",
"Platform" : "[WINDOWS, LINUX, etc..]"
}
}
Logout:
{
"EventName" : "player_logged_out",
"EventNamespace" : "abshooter", // Game Namespace
"Payload": {
"GameSessionId" : "generated after the game client is executed",
"UserId" : "could be obtained from player's credential information",
"LoginSessionId" : "generated after the player has been logged in",
"LoginSessionDuration" : "time unit is in minutes"
}
}
If you want to track when matchmaking starts and ends, you can use the following reference for your request body.
Start:
{
"EventName" : "player_match_start",
"EventNamespace" : "abshooter", // Game Namespace
"Payload": {
"GameSessionId" : "generated after the game client is executed",
"UserId" : "could be obtained from player's credential information",
"MatchId" : "obtained from lobby matchmaking service",
"ConnectToLocal" : [true, false], // Is using local DS
"GameMode" : "chosen game mode for current match"
}
}
End:
{
"EventName" : "player_match_end",
"EventNamespace" : "abshooter", // Game Namespace
"Payload": {
"GameSessionId" : "generated after the game client is executed",
"UserId" : "could be obtained from player's credential information",
"MatchId" : "obtained from lobby matchmaking service",
"IsWinner" : [true, false], // Is the player win
"EndReason" : "cause of end match"
}
}
If you want to detect a player's active status on the server, you can use the following reference for your request body.
{
"EventName" : "player_heartbeat",
"EventNamespace" : "abshooter", // Game Namespace
"Payload": {
"GameSessionId" : "generated after the game client is executed",
"UserId" : "could be obtained from player's credential information",
"IsServer" : [true, false] // Is it in the server
}
}
The Event Timestamp will be generated automatically by the Game Telemetry in ISO 8601 format (e.g., 2021-01-05T05:04:08.775Z).
The Event ID will be generated automatically by the Game Telemetry. Upon a successful request, the event will be sent to the designated streaming pipeline for tracking.