Accessing Configs Data and Profiles¶
Game Configs¶
Accessing Single Document¶
To access a specific document by its ID, you can use the following code:
var document = Balancy.CMS.GetModelByUnnyId<YourModel>(id);
const document = Balancy.CMS.getModelByUnnyId<YourModel>(id);
Example:
var item26 = Balancy.CMS.GetModelByUnnyId<Balancy.Models.SmartObjects.Item>("26");
Debug.Log($"item26.unnyId = {item26.UnnyId}");
Debug.Log($"item26.Name = {item26.Name}");
Debug.Log($"item26.MaxStack = {item26.MaxStack}");
const item26 = Balancy.CMS.getModelByUnnyId<SmartObjectsItem>("26");
console.log(`item26.unnyId = ${item26.unnyId}`);
console.log(`item26.Name = ${item26.name.getValue()}`);
console.log(`item26.MaxStack = ${item26.maxStack}`);
Accessing List of Documents¶
To get a list of all documents of a specific type, you can use the following code:
var documents = Balancy.CMS.GetModels<YourModel>(includeChildren);
const documents = Balancy.CMS.getModels<YourModel>(includeChildren);
includeChildren
- if true
, the method returns all documents of the specified type and their children. If false
, it returns only the documents of the specified type.
Example:
var allItems = Balancy.CMS.GetModels<Balancy.Models.SmartObjects.Item>(true);
Debug.Log("AllItems count = " + allItems.Length);
foreach (var item in allItems)
{
Debug.Log("=== New Item ===");
Debug.Log($"unnyId = {item.UnnyId}");
Debug.Log($"Name = {item.Name}");
Debug.Log($"MaxStack = {item.MaxStack}");
}
const allItems = Balancy.CMS.getModels<SmartObjectsItem>(true);
console.log(`AllItems count = ${allItems.length}`);
allItems.forEach(item => {
console.log("=== New Item ===");
console.log(`unnyId = ${item.unnyId}`);
console.log(`Name = ${item.name.getValue()}`);
console.log(`MaxStack = ${item.maxStack}`);
});
Profiles¶
Custom Profile¶
If you have a custom profile, you can easily access it:
var profile = Balancy.Profiles.Get<Profile>();
const profile = Balancy.Profiles.get<Profile>();
System Profile¶
The system profile contains various data points that are crucial for understanding the user's interactions and status in the application.
var systemProfile = Balancy.Profiles.System;
const systemProfile = Balancy.Profiles.system;
System Profile Fields¶
-
Payments: Provides access to payment-related information, including purchase history, total spend, VIP level, and other payment metrics.
- DaysForPurchase: Number of days since the last purchase.
- Purchases: List of individual purchases made by the user.
- TotalSpend: Total amount spent by the user.
- LastPaymentTime: Timestamp of the last payment.
- MaxPayment: Maximum payment made by the user.
- PaymentsCount: Total number of payments made.
- ResourcesMultiplier: Multiplier applied to resources from payments.
- LevelVIP: VIP level of the user.
- ComfortablePayment: A comfortable payment value determined by user behavior.
-
SmartInfo: Stores general LiveOps information
- GameOffers: List of offers available in the game.
- GameOfferGroups: Grouped offers available in the game.
- GameEvents: List of events happening in the game.
-
SegmentsInfo: Contains information about different user segments that the profile belongs to.
- Segments: List of user segments.
-
GeneralInfo: Holds general, non-categorized information about the user.
- PlayTime: Total playtime of the user.
- AppVersion: Version of the app used by the user.
- EngineVersion: Version of the game engine.
- Platform: Platform on which the app is running.
- PlatformId: Identifier for the platform.
- SystemLanguage: Language of the user's system.
- Country: User's country.
- TimeSincePurchase: Time elapsed since the last purchase.
- Session: Current session number.
- IsNewUser: Indicates if the user is new.
- FirstLoginTime: Timestamp of the user's first login.
- Level: Current level of the user.
- TutorialStep: Current tutorial step the user is on.
- TrafficSource: Source of user acquisition.
- DontDisturb: Indicates if the user has enabled Do Not Disturb.
- LastLoginTime: Timestamp of the last login.
- CurrentDay: Current in-game day.
- TrafficCampaign: Campaign associated with user acquisition.
- ProfileId: Unique identifier for the user's profile.
- DeviceId: Unique device identifier.
- CustomId: Custom identifier set by the application.
- GameLocalization: Localization settings for the game.
- TimeSinceInstall: Time elapsed since the app was installed.
- DeviceModel: Model of the user's device.
- DeviceName: Name of the user's device.
- DeviceType: Type of device (e.g., mobile, tablet).
- OperatingSystem: Operating system of the user's device.
- OperatingSystemFamily: Family of the operating system.
- SystemMemorySize: Size of the system memory.
- InstallVersion: Version of the app at the time of installation.
-
TestsInfo: Stores information regarding A/B tests that the user is currently involved in.
- Tests: List of A/B tests.
- AvoidedTests: List of tests that the user has opted out of.
-
AdsInfo: Provides data on ads viewed or interacted with by the user.
- RevenueTotal: Total revenue generated from ads.
- AdRewarded: Information about rewarded ads.
- AdInterstitial: Information about interstitial ads.
- AdCustom: Information about custom ads.
- InterstitialAdsPeriod: Time period between interstitial ads.
- RevenueToday: Revenue generated from ads today.
-
LiveOpsInfo: Contains information related to additional LiveOps activities, such as Daily Bonus.
- DailyRewardCollected: Indicates if the daily reward has been collected.
- DailyRewardCollectTime: Timestamp of the last daily reward collection.
-
Inventories: Tracks inventory-related data for the user, such as items and counts.
- Currencies: Information about in-game currencies.
- Items: Information about in-game items.
Reset Account (All Profiles)¶
To reset all profiles, use the following code:
Balancy.Profiles.Reset();
Balancy.Profiles.reset();
The reset is instant, and you can access fresh profiles immediately after the reset.
Game Events and Offers¶
Use LiveOps Callbacks to receive notifications about update statuses of Events and Offers at runtime. Use one of the methods below to request the list of active Events or Offers:
var smartInfo = Balancy.Profiles.System.SmartInfo;
var activeGameEvents = smartInfo.GameEvents;
var activeOffers = smartInfo.GameOffers;
var activeOfferGroups = smartInfo.GameOfferGroups;
const smartInfo = Balancy.Profiles.system.smartInfo;
const activeGameEvents = smartInfo.gameEvents;
const activeOffers = smartInfo.gameOffers;
const activeOfferGroups = smartInfo.gameOfferGroups;
There are several methods you can use to know how much time is left for an event or offer to end or to start.
offerInfo.GetSecondsLeftBeforeDeactivation();//offerInfo is an element of Balancy.Profiles.System.SmartsInfo.GameOffers
eventInfo.GetSecondsLeftBeforeDeactivation();//eventInfo is an element of Balancy.Profiles.System.SmartsInfo.GameEvents
gameEvent.GetSecondsLeftBeforeDeactivation();
gameEvent.GetSecondsBeforeActivation(ignoreTriggers);
offerInfo.getSecondsLeftBeforeDeactivation();//offerInfo is an element of Balancy.Profiles.system.smartsInfo.gameOffers
eventInfo.getSecondsLeftBeforeDeactivation();//eventInfo is an element of Balancy.Profiles.system.smartsInfo.gameEvents
gameEvent.getSecondsLeftBeforeDeactivation();
gameEvent.getSecondsBeforeActivation(ignoreTriggers);
Some of the conditions might have complex logic and include not only the time, but also some user properties or segmentations. You can pass ignoreTriggers=true to ignore such conditions.
A/B Tests¶
Use LiveOps Callbacks to receive notifications about new A/B Tests at runtime. Use the method below to request the list of active A/B Tests:
var myAbTests = Balancy.Profiles.System.TestsInfo.Tests;
foreach (var myAbTest in myAbTests)
Debug.Log($"My Test {myAbTest.Test?.Name} variant = {myAbTest.Variant?.Name} finished = {myAbTest.Finished}");
const myAbTests = Balancy.Profiles.system.testsInfo.tests;
for (let i = 0;i< myAbTests.count;i++) {
const myAbTest = myAbTests.get(i);
console.log(i, ")", myAbTest.test?.name, "variant = ", myAbTest.variant?.name, " finished = ", myAbTest.finished);
}
Segmentation¶
Use LiveOps Callbacks to receive notifications about changes in Segmentation at runtime. Use the method below to request the status of your Segments.
var mySegments = Balancy.Profiles.System.SegmentsInfo.Segments;
foreach (var mySegment in mySegments) {
if (mySegment.IsIn)
Debug.Log($"My Segment {mySegment.Segment?.Name}");
}
const mySegments = Balancy.Profiles.system.segmentsInfo.segments;
for (let i = 0;i < mySegments.count;i++) {
const mySegment = mySegments.get(i);
if (mySegment.isIn)
console.log("My Segment " + mySegment.segment?.name);
}
Daily Bonus¶
Balancy provides built-in support for Daily Bonuses, allowing developers to configure and manage recurring rewards that players can claim on a daily basis. The system supports various types of daily bonuses, including calendar-based rewards, streak-based rewards, and flexible reset rules.
Accessing Daily Bonuses¶
To access the list of available Daily Bonuses, use the following method:
var dailyBonuses = Balancy.Profiles.System.LiveOpsInfo.DailyBonusInfos;
const dailyBonuses = Balancy.Profiles.system.liveOpsInfo.dailyBonusInfos;
This returns an array of DailyBonusInfo
objects, each representing a specific daily bonus configuration.
Checking Next Reward Availability¶
To check when the next reward will be available:
int secondsTillNextReward = dailyBonusInfo.GetSecondsTillTheNextReward();
Debug.Log($"Next reward available in: {secondsTillNextReward} seconds");
const secondsTillNextReward = dailyBonusInfo.getSecondsTillTheNextReward();
console.log(`Next reward available in: ${secondsTillNextReward} seconds`);
If secondsTillNextReward
is 0
, the player can immediately claim their next reward.
Checking Reward Eligibility¶
Before claiming a reward, you can check if it's available:
bool canClaim = dailyBonusInfo.CanClaimNextReward();
Debug.Log($"Can claim next reward: {canClaim}");
const canClaim = dailyBonusInfo.canClaimNextReward();
console.log(`Can claim next reward: ${canClaim}`);
Claiming the Next Reward¶
To claim the next available daily reward:
var result = dailyBonusInfo.ClaimNextReward();
Debug.Log($"Claimed reward: {result}");
const result = dailyBonusInfo.claimNextReward();
console.log("Claimed reward:", result);
After a reward is claimed, the system automatically updates the bonus state.
Listening for Daily Bonus Updates¶
Since daily bonuses may change dynamically, it's recommended to subscribe to updates:
Balancy.Callbacks.OnDailyBonusUpdated += () =>
{
Debug.Log("Daily bonus data updated.");
};
const updateCallback = () => {
console.log("Daily bonus data updated.");
};
const callbackId = Balancy.Callbacks.onDailyBonusUpdated.subscribe(updateCallback);
// Unsubscribe when no longer needed
Balancy.Callbacks.onDailyBonusUpdated.unsubscribe(callbackId);
Understanding Daily Bonus Types¶
Balancy supports multiple types of daily bonus resets:
Bonus Type | Description |
---|---|
Collect All to Reset | The reward sequence resets only after all rewards are collected. |
Skip to Reset | If the player misses a reward, the sequence resets. |
Calendar Reset | Rewards reset based on a calendar cycle, independent of player activity. If all the rewards are claimed, user can claim the Bonus Reward every day before the next cycle. |
Skip to Reset (Current Week) | The sequence resets weekly if any reward is skipped. |
To determine the reset type of a daily bonus:
Debug.Log($"Daily Bonus Type: {dailyBonusInfo.DailyBonus.Type}");
console.log(`Daily Bonus Type: ${dailyBonusInfo.dailyBonus?.type}`);
This helps in displaying relevant UI prompts based on how the bonus operates.
Displaying Rewards¶
You can iterate over the daily bonus rewards:
var rewards = dailyBonusInfo.DailyBonus.Rewards;
for (int day = 1; day <= rewards.Length; day++)
{
var rewardItem = rewards.Items[0];//Assuming that each day has only one reward, you can iterate over the rewards.Items array if there are multiple rewards
Debug.Log($"Day {day}: {rewardItem.Item?.Name} x {rewardItem.Count}");
}
dailyBonusInfo.dailyBonus?.rewards.forEach((reward, index) => {
//Assuming that each day has only one reward, you can iterate over the reward.items array if there are multiple rewards
console.log(`Day ${index + 1}: ${reward.items[0]?.item?.name.value} x ${reward.items[0]?.count}`);
});
This allows you to display all upcoming rewards for players.
Using these methods, you can efficiently manage daily login rewards, ensuring a smooth user experience while leveraging Balancy’s automated reward tracking.
Game Shops¶
Balancy provides a Game Shops system that allows developers to configure and manage in-game stores dynamically. The system supports multiple shop configurations, each containing pages and slots for various store items.
Accessing Available Shops¶
To retrieve the list of available Game Shops, use the following method:
var gameShops = Balancy.Profiles.System.ShopsInfo.GameShops;
const gameShops = Balancy.Profiles.system.shopsInfo.gameShops;
This returns an array of GameShop
objects, each representing a unique shop configuration.
Selecting a Shop and Pages¶
A Game Shop can have multiple pages. You can retrieve and select a specific page:
var activeShop = gameShops.FirstOrDefault();
var shopPages = activeShop?.ActivePages;
var selectedPage = shopPages?.FirstOrDefault();
const activeShop = gameShops.count > 0 ? gameShops.get(0) : null;
const shopPages = activeShop?.activePages?.toArray() || [];
const selectedPage = shopPages.length > 0 ? shopPages[0] : null;
Once a page is selected, it displays a subset of store items available in that shop.
Listing Shop Slots and Store Items¶
Each Shop Page contains multiple Shop Slots, which reference store items available for purchase.
var shopSlots = selectedPage?.ActiveSlots;
foreach (var shopSlot in shopSlots)
{
var storeItem = shopSlot.Slot?.StoreItem;
Debug.Log($"Item: {storeItem?.Name}");
Debug.Log($"Price: {storeItem?.Price?.Product?.Price}");
}
const shopSlots = selectedPage?.activeSlots?.toArray() || [];
shopSlots.forEach(shopSlot => {
const storeItem = shopSlot.slot?.storeItem;
console.log(`Item: ${storeItem?.name?.value}`);
console.log(`Price: ${storeItem?.price?.product?.price}`);
});
Purchasing a Store Item¶
For details on purchasing methods, refer to the API Documentation.
Listening for Shop Updates¶
Since shop contents may change dynamically, subscribe to onShopUpdated to refresh the available store items:
Balancy.Callbacks.OnShopUpdated += () =>
{
Debug.Log("Shop data updated.");
};
const shopUpdatedId = Balancy.Callbacks.onShopUpdated.subscribe(() => {
console.log("Shop data updated.");
});
// Unsubscribe when no longer needed
Balancy.Callbacks.onShopUpdated.unsubscribe(shopUpdatedId);
Displaying Shops and Pages¶
Developers can display multiple Game Shops with horizontal scrolling to select a Shop Page.
Rendering Available Shop Pages¶
foreach (var page in shopPages)
{
Debug.Log($"Shop Page: {page.Page?.Name}");
}
shopPages.forEach(page => {
console.log(`Shop Page: ${page.page?.name?.value}`);
});
Developers can then update the UI to allow users to switch between pages dynamically.
Rendering Store Items in a Grid¶
Store items can be displayed in a grid layout for easy navigation.
foreach (var shopSlot in selectedPage?.ActiveSlots)
{
var storeItem = shopSlot.Slot?.StoreItem;
Debug.Log($"Item: {storeItem?.Name}, Price: {storeItem?.Price?.Product?.Price}");
}
shopSlots.forEach(shopSlot => {
const storeItem = shopSlot.slot?.storeItem;
console.log(`Item: ${storeItem?.name?.value}, Price: ${storeItem?.price?.product?.price}`);
});
Using these methods, you can create a fully dynamic in-game shop system where items, pages, and purchase logic are seamlessly managed by Balancy.