# Version 2.x.x

The user needs to call functions at certain points in the game to send information to the data analysis server, which can then view the analyzed data at [data4game.com](http://data4game.com/).&#x20;

Instructions for viewing detailed figures are available at <https://falcon-game-studio.gitbook.io/falcon-bigdata/giai-thich-bieu-do/tong-quan>

Currently, API is providing 8 functions that call statistics:

* [`LevelLog`](#1.1.-level-log): game level statistic.
* [`​InAppLog`](#1.2.-inapp-log): player in-app statistic.
* [`AdsLog`](#1.3.-advertisement-log): player ad watch statistic.
* [`ResourceLog`](#1.4.-resource-log): player resource get/use statistic.
* [`SessionLog`](#1.5.-session-log): player playtime statistic.
* [`FunnelLog`](#1.6.-funnellog): designed to hierarchize players according to any property.
* [`PropretyLog`](#1.7.-property-log-dang-trong-giai-doan-thu-nghiem-chua-san-sang-su-dung) : Dynamic statistics of events/features/items players have unlocked, designed for players to define a dynamic graph themselves.
* [`ActionLog`](#1.8.-action-log): Statistics the movement between 2 player behaviors, designed to track the order and analyze user behavior.

At the same time, there are 2 logs that are performed automatically:

* RetentionLog: player retention statistic.
* UserTotalTimeLog: statistics of the player's total gaming time per play.

Details of the above automatic log functions can be viewed at [Automatic Logs](https://falcon-game-studio.gitbook.io/falcon-sdk/falcon-analytics/2.-automatic-logs).

<mark style="color:orange;">Note:</mark>

* The parameters in the functions, if there is no separate note, then all need to enter a value other than null.
* The strlen in the note (if any) is the length of the input string value.
* If the player does not have internet access when playing the game, i.e. cannot send logs to the server, the SDK will automatically save and send when the network is restored, but this saving only contains a maximum of 100 messages.
* If you need to change a specific statistical data field, you can refer [PlayerParams](https://falcon-game-studio.gitbook.io/falcon-sdk/falcon-analytics/4.-fplayerinforepo/version-2.x.x).
* As of version 2.2.2, we no longer remove error logs but will try to return the value to the correct format. This is done in order not to ignore any event of the player, helping to ensure the full push of the data. <mark style="color:red;">However, when using these versions, users must ensure the logic of LevelLog and FunnelLog themselves.</mark>

## 1.1. Level log

Call every time the player finishes a new level in the game.

The function structure is:

```
void DWHLog.Log.LevelLog(int level, TimeSpan duration, int wave, string difficulty, LevelStatus status)
```

* `int level`: Playing level.<mark style="color:red;">(≥ 0)</mark>&#x20;
* `TimeSpan duration`: The time the player uses for the level.
* `int wave`: Number of waves the player passes (before failing, or the total number of waves of the level if the player passes). <mark style="color:red;">(≥ 0)</mark>&#x20;
* `string difficulty`: The difficulty of the playing level(*`"easy"`, `"hard"`, `"no hope"`*, ...) <mark style="color:red;">(1 ≤ strlen ≤ 20)</mark>
* `LevelStatus status`: The current status of the level when ending (*`LevelStatus.pass`, `LevelStatus.fail`*).

EXP:&#x20;

* *`DWHLog.Log.LevelLog(2, 103, 5, "normal", LevelStatus.pass)`*
* *`DWHLog.Log.LevelLog(50, 69, 0, "hard", LevelStatus.fail)`*

<mark style="color:red;">**Basic logic:**</mark>

* If the player has passed the level he is playing before, the log will not be sent (i.e. only log cases with levels the player has never passed).
* If the player has never passed the playing level, if:
  * LevelStatus == pass: Send logs to the server and save the level value for future processing.
  * LevelStatus == fail: Send log to the server.

<mark style="color:red;">**Note**</mark>**:**&#x20;

* The log level is only sent to the server if the player has never passed the level, that is, if the player has passed level x, the log will only be sent when the level of the new log is different from x.
* Some versions have the level value named maxPassedLevel, which will be fixed in later versions.

## 1.2. InApp log

Call after the player makes an InApp purchase in the game.

The function structure is:

```
void DWHLog.Log.InappLog(string productId, string currencyCode, decimal price, string transactionId, string purchaseToken, string where)
```

* `string productId`: ID of the in-app package.<mark style="color:red;">(1 ≤ strlen ≤ 100)</mark>
* `string currencyCode`: Which currency do players deposit through <mark style="color:red;">(Following</mark> [<mark style="color:blue;">ISO 4217 currency codes</mark>](https://www.iban.com/currency-codes)<mark style="color:red;">, means "USD" instead of "$", "dollar", "usDollar", ...)</mark>
* `decimal price`: Pricing of the recharge package.<mark style="color:red;">(1 ≤ strlen ≤ 20)</mark>
* `string transactionId.`
* `string purchaseToken`: The token that Google Play returns after the transaction, otherwise it will be input with an empty string ("").
* `string where`:  Deposit location (Recharge in the shop / in the pop-up package at the end of the level,...)<mark style="color:red;">(1 ≤ strlen ≤ 200)</mark>

EXP:&#x20;

* *`DWHLog.Log.InappLog(8, "pack_gem_20usd", "USD", 30.99m,"GPA.330...528", "ffdhjgcgjamj ... CiSwg", "Level_45")`*
* *`DWHLog.Log.InappLog(15, "daily_pack_1", "KRW", 8400m,"GPA.335...779", "fcdfhoogaefl ... HMtQQ", "shop")`*

## 1.3. Advertisement log

Call after the player finishes watching ads in the game.

The function structure is:

```
void DWHLog.Log.AdsLog(int maxPassedLevel, AdType type, string adWhere)
```

* `int maxPassedLevel:`The maximum level that the player has passed. <mark style="color:red;">(≥ 0)</mark>&#x20;
* `AdType type`: Type of ad watched (*`AdType.interstitial`, `AdType.reward`)*
* `string adWhere`: Where to view AD (View in the shop, view in the level to revive/get rewards,...) <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>

or:

```
void DWHLog.Log.AdsLog(AdType type, string adWhere)
```

* `AdType type`: Type of ad watched (*`AdType.interstitial`, `AdType.reward`)*
* `string adWhere`: Where to view AD (View in the shop, view in the level to revive/get rewards,...) <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>

EXP:&#x20;

* *`DWHLog.Log.AdsLog(15, AdType.interstitial, "Video_RandomEndgame")`*
* *`DWHLog.Log.AdsLog(4, AdType.reward, "Video_Revival")`*

## 1.4. Resource log

Call every time the player receives/uses resources in the game.

The function structure is:

```
void DWHLog.Log.ResourceLog(int maxPassedLevel, FlowType flowType, string itemType, string itemId, string currency, long amount)
```

* `int maxPassedLevel`: The maximum level that the player has passed. <mark style="color:red;">(≥ 0)</mark>&#x20;
* `FlowType flowType`: Player gets/uses resources (FlowType.source - get, FlowType.sink - use).
* `string itemType`: The resource supplement/consumption (in general) <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `string itemId`: The resource supplement/consumption (in specific) <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `string currency`: Type of resources players get (gem, gold, crystal, ...) <mark style="color:red;">(1 ≤ strlen ≤ 20)</mark>
* `long amount`: The amount of resources the player receives<mark style="color:red;">(≥ 0)</mark>&#x20;

or:

```
void DWHLog.Log.ResourceLog(FlowType flowType, string itemType, string itemId, string currency, long amount)
```

* `FlowType flowType`: Player gets/uses resources (FlowType.source - get, FlowType.sink - use).
* `string itemType`: The resource supplement/consumption (in general) <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `string itemId`: The resource supplement/consumption (in specific) <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `string currency`: Type of resources players get (gem, gold, crystal, ...) <mark style="color:red;">(1 ≤ strlen ≤ 20)</mark>
* `long amount`: The amount of resources the player receives<mark style="color:red;">(≥ 0)</mark>&#x20;

EXP:&#x20;

* *`DWHLog.Log.ResourceLog(13, FlowType.source, "login", "login","gem", 2)`*
* *`DWHLog.Log.ResourceLog(5, FlowType.sink, "upgrade", "upgrade_weapon","gold", 4185)`*

Note: itemId can be thought of as subType for itemType, a more detailed annotation for the resource (for example, for the same upgrade in itemType, but itemId will be more detailed such as upgradeWeapon / upgradeCharacter / ...), for convenient analysis charting.

## 1.5. Session log

Calling each end measures the amount of time the player spends on a feature (event, ...)

The function structure is:

```
void DWHLog.Log.SessionLog(int maxPassedLevel, TimeSpan sessionTime, string gameMod)
```

* `int maxPassedLevel`: The maximum level that the player has passed. <mark style="color:red;">(≥ 0)</mark>&#x20;
* `TimeSpan sessionTime`: Total time the player uses for the feature <mark style="color:red;">(5 secs ≤ sessionTime ≤  2 days)</mark>
* `string gameMod`: Feature name.<mark style="color:red;">(1 ≤ strlen ≤ 100)</mark>

or:

```
void DWHLog.Log.SessionLog(TimeSpan sessionTime, string gameMod)
```

* `TimeSpan sesionTime`: Total time the player uses for the feature <mark style="color:red;">(5 secs ≤ sessionTime ≤  2 days)</mark>
* `string gameMod`: Feature name.<mark style="color:red;">(1 ≤ strlen ≤ 100)</mark>

EXP:&#x20;

* *`DWHLog.Log.SessionLog(10, 1864, "event_christmas_day1_2021")`*
* *`DWHLog.Log.SessionLog(4063, "daily_gameplay")`*

## 1.6. FunnelLog

It is a log used to draw a funnel chart, which creates blocking levels and filters players showing the percentage of players who passed each level.

The function structure is:

```
public DwhFunnelLog(int maxPassedLevel, string funnelName, string action, int priority)
```

* `int maxPassedLevel`: The maximum level that the player has passed. <mark style="color:red;">(≥ 0)</mark>&#x20;
* `string funnelName`: The name of the funnel chart <mark style="color:red;">(1 ≤ strlen ≤ 200)</mark>
* `string action`: Name of the level in the funnel <mark style="color:red;">(1 ≤ strlen ≤ 200)</mark>
* `int priority`: The order of the level in the funnel <mark style="color:red;">(count from 0)</mark>

or:

```
public DwhFunnelLog(string funnelName, string action, int priority)
```

* `string funnelName`: The name of the funnel chart <mark style="color:red;">(1 ≤ strlen ≤ 200)</mark>
* `string action`: Name of the level in the funnel <mark style="color:red;">(1 ≤ strlen ≤ 200)</mark>
* `int priority`: The order of the level in the funnel <mark style="color:red;">(count from 0)</mark>

EXP:&#x20;

* *`DWHLog.Log.`DwhFunnelLog`(20, "inapp_purchase", "whale", 17)`*
* *`DWHLog.Log.`DwhFunnelLog`(5, "story_line", "chapter_7", 53)`*

<mark style="color:red;">**Basic logic:**</mark>

* If the priority is greater than 0, and there has never been a log of the priority before with the same funnelName (like the priority is logged as 5 with funnelName as "level" but the system recognizes that it has never logged with priority 4 with funnelName as "level") -> log in the wrong order -> does not send logs -> the log sending needs to be done in the correct order of priority 0 -> 1 -> 2 -> 3 -> ...
* If the system recognizes the previous current log priority with the same funnelName (currently log funnelName is "level", priority is 4 but in the past also logged funnelName is "level", priority is 4), then the current log will be evaluated as duplicate and not submitted.

<mark style="color:red;">Note:</mark> According to the nature of the funnel chart, players must pass each block level in ascending order, so the player's log must also be done in turn, the log will not be sent if the log is in the wrong order, for example, if the player has logged the funnel "play\_date" with priorities 0 -> 1 -> 2 -> 3 (ie currently at level 3), then the player will have to log the funnel "play\_date" at priority 4, not at other levels such as 5, 9, 2, ...

## 1.7. Property log

Call every time the player unlocks 1 feature, item, event,... This is a log designed to help users dynamically define the value they want to synthesize.

The function structure is:

```
void DWHLog.Log.PropertyLog(int maxPassedLevel, string name, string value, int priority)
```

* `int maxPassedLevel`: The maximum level that the player has passed. <mark style="color:red;">(≥ 0)</mark>&#x20;
* `string name`: Name of the type of feature/item unlocked <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `string value`: Type of Feature/Item unlocked <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `int priority`: Hierarchy, the order of the property, is used by the server to sort and chart. <mark style="color:red;">(≥ 0)</mark>&#x20;

or:

```
void DWHLog.Log.PropertyLog(string name, string value, int priority)
```

* `string name`: Name of the type of feature/item unlocked <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `string value`: Type of Feature/Item unlocked <mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `int priority`: Hierarchy, the order of the property, is used by the server to sort and chart. <mark style="color:red;">(≥ 0)</mark>&#x20;

EXP:&#x20;

* *`DWHLog.Log.PropertyLog(99, "weapon", "holy_moly_whack_a_moley_legendary_cannon", 99999)`*
* *`DWHLog.Log.PropertyLog(69, "level", "super_secret_hidden_level",5)`*
* *`DWHLog.Log.PropertyLog(96, "mission", "extremly_difficult_mission_that_nobody_can_complete",18)`*

## 1.8. Action log

<mark style="color:red;">We are testing this log more closely, so in the process, the call of this log may be different on the doc.</mark>

Call when the player has just switched between two actions/events/scene/panel/etc. This is a type of log designed to track the order and analyze user behavior.

The function structure is:

```
void DWHLog.Log.ActionLog(string from, string to, TimeSpan time, int priority)
```

* `string from`: previous actions of the player.<mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* `string to`: The player's current actions.<mark style="color:red;">(1 ≤ strlen ≤ 50)</mark>
* TimeSpan `time`: The time the player spends on the previous action before switching.
* `int priority`: Hierarchy, order of action (for the server to analyze and chart).

EXP:&#x20;

* *`DWHLog.Log.ActionLog("shop", "homescene", 965, 12)`*
* *`DWHLog.Log.ActionLog("weapon_upgrade_scene", "play_level", 30, 1)`*
* *`DWHLog.Log.ActionLog("minigame_select_panel", "đạp_zịt_game",985, 5)`*
