- Last Updated
Vietnam Regulation
Development
Mobile
This is the flow for registering the health-warning callback (setPlaytimeListener) based on play time. After SDK initialization, if you register the listener, you receive one callback right after login completes, and thereafter a callback is delivered every daily_play_limit_sec interval. On iOS, the same flow is handled with an NSNotificationCenter observer approach.
Prerequisites
- The
daily_play_limit_secvalue must be set in the Partners SDK Config. - Register the listener/observer after
Auth.initializecompletes. Registering before initialization means the callback isn't delivered. - On iOS, release the observer with
removeObserverwhen the component that registered it is released, to prevent leaks.
Development Flow
- Register the listener: after the SDK-initialization-complete callback, register
Auth.setPlaytimeListener(Android/Unity) or theSGSPlaytimeDidUpdateNotificationobserver (iOS). - Wait for login completion: when the user completes login, the timer activates and one callback is delivered.
- Handle periodic callbacks: on each subsequent callback, show the health-warning message/UI on the game screen. To avoid blocking gameplay, a non-blocking UI (toast, banner, etc.) is recommended.
Troubleshooting
| Situation | Cause | Solution |
|---|---|---|
| The callback is never called | You registered the listener before SDK initialization/login completed, or the build isn't a STOVE VN environment. | Adjust the call order so the listener is registered after the Auth.initialize success callback. Since it's a STOVE-VN-only feature, the callback doesn't occur in builds for other regions. |
| The callback interval differs from expected | The Partners daily_play_limit_sec value is set differently than intended, or the Config at build time isn't the latest. | Check the daily_play_limit_sec value in Partners and update it to the desired interval, then verify by re-logging in or restarting the app so the client fetches the latest Config. |
| A memory leak occurs on iOS | You didn't call removeObserver when the component that registered the observer was released. | Call [[NSNotificationCenter defaultCenter] removeObserver:self] in the dealloc of the object that registered the observer (or at the end of its lifecycle). |
Sample Code
public void SetPlaytimeListener()
{
Auth.SetPlaytimeListener(playtimeInfo =>
{
// Callback at each interval set in Partners
// daily_play_limit_sec: when set to 1800, handled every 30 minutes
});
}
PC
This is the flow for integrating Vietnam age-rating display and the overindulgence notification via the PC SDK (Base SDK). For both features, once you register the callback, the SDK delivers overlay-display info and the game renders the overlay itself using that info.
Prerequisites
To service a game in Vietnam, you must show the age-rating display and the overindulgence notification on screen. When the STOVE PC SDK's Base SDK delivers these two regulatory pieces of info via callback, the game draws the overlay UI itself using the delivered info. This is a required item for Vietnam service.
To use the Vietnam-regulation features, you must first integrate the Base SDK into the game. For how to integrate the Base SDK, refer to the Base SDK Integration document.
- The Base SDK must be initialized via
Base_Initialize. - The SDK's asynchronous callbacks run on the thread that calls
Base_RunCallback(). You must callBase_RunCallback()periodically in the game loop for callbacks to work correctly. - For both callbacks, call the API after overlay rendering is possible, or store the delivered info and use it when rendering becomes possible.
- For the Vietnam-regulation features, the registered callbacks are released automatically when
Base_UnInitializeis called.
These are the design guide and image resources you can reference when integrating the Vietnam game-restriction API directly.
Development Flow
Two Regulation Features
| Feature | API | Description |
|---|---|---|
| Age-rating display | Base_VietnamAgeRatingNotification |
Always displays the game's age-rating info as an overlay. When the SDK delivers the overlay's position, size, opacity, and type info via callback, the game renders the overlay itself. |
| Overindulgence notification | Base_VietnamOverimmersionNotification |
Displays an overindulgence warning based on play time as an overlay at set intervals. It delivers the overlay show/hide/expand state via callback along with the warning message, elapsed time, and display time. |
Differences from Korea's Overindulgence Prevention
For Korea's overindulgence prevention, the game only needs to display the message, elapsed time, and display time received in the callback. For Vietnam regulation, the game receives additional info beyond the message—coordinates, opacity, size, type, etc.—via callback and must implement the overlay itself. The game also controls display based on the overlay display state (SHOW/HIDE/EXPANDED). Age-rating display and the overindulgence notification are separated into distinct APIs.
Overlay Display State (StoveOverlayState / StoveOverlayMode)
These are the overlay-display state values delivered via callback.
| Value | State | Description |
|---|---|---|
| 0 | SHOW | Age rating: shows the overlay. Overindulgence: the timer activates (no display needed). |
| 1 | HIDE | Hides the overlay. |
| 2 | EXPANDED | Shows the overlay expanded. Used only for overindulgence, not for age rating. |
How to Apply Callback-Struct Fields
Apply each field of the struct delivered via callback as follows.
| Field | How to apply |
|---|---|
| overlayMode | The overlay display state. Age rating uses only SHOW/HIDE; overindulgence uses SHOW/EXPANDED/HIDE. |
| overlayType | 0 = Black theme (dark background, suits a bright game screen), 1 = White theme (light background, suits a dark game screen). Age rating sets the badge image matching the theme, and overindulgence sets the background color, per this value. |
| overlayScale | A multiplier against the base size of 3% of the screen area. 1.0 is exactly 3% area, and 0.5 is half of that. Multiply the base size by this value to determine the final overlay size. |
| overlayOpacity | A range from 0.0 (fully transparent) to 1.0 (fully opaque). Currently 1.0 is always delivered; it's a reserved field for possible future regulation changes. Always display it opaque. |
| ageRating | The game rating. 0 = all ages, 12 = age 12, 16 = age 16, 18 = age 18. Used to select the display image matching the rating. |
| displayPositionX / displayPositionY | Normalized coordinates from 0.0 to 1.0. The top-left of the screen is (0.0, 0.0) and the bottom-right is (1.0, 1.0). Convert to pixel coordinates for your game resolution (e.g., actualX = displayPositionX × screen width). The coordinates are based on the overlay's center point, and clamping is needed so it doesn't go off-screen. |
| message | A notice message translated by the SDK into the currently set language. Display it in the text UI as-is. |
| language | The currently applied language code (e.g., "vi", "en", "ko"). You can use it for additional in-game localization if needed. |
Overlay Implementation Criteria
- Per legal requirements, the age-rating image must be shown at 3% or more of the game screen area. The overindulgence overlay is based on the same height as the age-rating image.
- The age-rating overlay is always shown by default; don't hide it arbitrarily in the game until
HIDEis delivered via callback. Its display position is fixed at the top-left, and you apply thedisplayPositionX/Yvalues delivered via callback as-is. - You must prepare 8 badge images yourself in the game: per rating (0/12/16/18) × per theme (Black/White). The SDK doesn't include the images. The badge images must include the age rating and notice text, so separate text rendering isn't needed.
- For the overindulgence overlay background color, use
#212121for the Black theme (overlayType=0) and#FFFFFFfor the White theme (overlayType=1). For text color, use white for the Black theme and black for the White theme. - The overindulgence
styledMessagecan include markup tags such as<b>...</b>and<color=#RRGGBBAA>...</color>. Use the game engine's rich-text feature to apply styling, and if rich text isn't supported, use the plain text inmessage.
The recommended overlay-text fonts are Pretendard for ko (Korean) and ja (Japanese), Anton for en (English) and vi (Vietnamese), and Noto Sans for zh-cn/zh-tw (Chinese), th (Thai), etc. For the detailed UI guide, refer to the design guide document.
Sample Code
These are the integration flow and code examples for the two features: age-rating display and the overindulgence notification.
Vietnam Age-Rating Display
Integrate via the Base_VietnamAgeRatingNotification API. The callback is called whenever the age-rating overlay needs to be shown/hidden. The callback struct StovePCVietnamAgeRatingInfo contains the overlay state, type, size, opacity, age rating, notice message, display position, and language code.
- Show the overlay when
overlayModeisSHOW, and hide it whenHIDE. (EXPANDEDisn't used for age rating.) - The age-rating callback is called only once on SHOW, so call the API after rendering is possible, or store the delivered info and use it later.
// 1. Include the BaseSDK header.
#include "BaseSDK.h"
using namespace Stove::PCSDK::Base;
// 2. The callback is a one-time notification called at each SHOW/HIDE point, and must be called after rendering is possible.
void Base_VietnamAgeRatingNotification_Example()
{
Base_VietnamAgeRatingNotification(
[](CallbackResult callbackResult, StovePCVietnamAgeRatingInfo vietnamAgeRatingInfo)
{
if (callbackResult.GetResult().IsSuccessful())
{
StoveOverlayState overlayState = vietnamAgeRatingInfo.GetOverlayState();
if (overlayState == StoveOverlayState::SHOW)
{
// Show the overlay
int overlayType = vietnamAgeRatingInfo.GetOverlayType();
float scale = vietnamAgeRatingInfo.GetOverlayScale();
float opacity = vietnamAgeRatingInfo.GetOverlayOpacity();
int ageRating = vietnamAgeRatingInfo.GetAgeRating();
const wchar_t* message = vietnamAgeRatingInfo.GetAgeRatingMessage();
float posX = vietnamAgeRatingInfo.GetDisplayPositionX();
float posY = vietnamAgeRatingInfo.GetDisplayPositionY();
const wchar_t* language = vietnamAgeRatingInfo.GetLanguage();
// Render the overlay UI with the delivered info
}
else if (overlayState == StoveOverlayState::HIDE)
{
// Hide the overlay
}
}
else
{
// Implement the failure logic.
}
}
);
}
Vietnam Overindulgence Notification
Integrate via the Base_VietnamOverimmersionNotification API. After the game starts, the callback is called at the time intervals prescribed by law. The callback struct StovePCVietnamOverimmersionInfo contains the overlay state, type, size, opacity, age rating, overindulgence warning message, styled message, elapsed time, display time, expand-animation time, display position, and language code.
- Handle it per
overlayMode.SHOWactivates the timer (no display needed),EXPANDEDshows the overlay (expanding along the X-axis from the center point duringexpandAnimationTime, with full height maintained from the start), andHIDEhides it. - Show the overlay for
exposureTime(seconds), then hide it automatically. - The overindulgence callback is also called once right after the game starts (0 minutes), so call the API after rendering is possible, or store the delivered info and use it later.
// 1. Include the BaseSDK header.
#include "BaseSDK.h"
using namespace Stove::PCSDK::Base;
// 2. The callback is also called once right after the game starts (0 minutes), and must be called after rendering is possible.
void Base_VietnamOverimmersionNotification_Example()
{
Base_VietnamOverimmersionNotification(
[](CallbackResult callbackResult, StovePCVietnamOverimmersionInfo vietnamOverimmersionInfo)
{
if (callbackResult.GetResult().IsSuccessful())
{
StoveOverlayState overlayState = vietnamOverimmersionInfo.GetOverlayState();
if (overlayState == StoveOverlayState::SHOW)
{
// Show the overlay in collapsed state (timer activated)
int overlayType = vietnamOverimmersionInfo.GetOverlayType();
float scale = vietnamOverimmersionInfo.GetOverlayScale();
float opacity = vietnamOverimmersionInfo.GetOverlayOpacity();
const wchar_t* message = vietnamOverimmersionInfo.GetOverimmersionMessage();
const wchar_t* styledMessage = vietnamOverimmersionInfo.GetStyledMessage();
int32_t elapsedTime = vietnamOverimmersionInfo.GetElapsedTime();
int32_t exposureTime = vietnamOverimmersionInfo.GetExposureTime();
float posX = vietnamOverimmersionInfo.GetDisplayPositionX();
float posY = vietnamOverimmersionInfo.GetDisplayPositionY();
const wchar_t* language = vietnamOverimmersionInfo.GetLanguage();
// Render the overlay UI with the delivered info
}
else if (overlayState == StoveOverlayState::EXPANDED)
{
// Show the overlay in expanded state
float expandAnimationTime = vietnamOverimmersionInfo.GetExpandAnimationTime();
// Handle the expand animation during expandAnimationTime
}
else if (overlayState == StoveOverlayState::HIDE)
{
// Hide the overlay
}
}
else
{
// Implement the failure logic.
}
}
);
}
Troubleshooting
The Vietnam-regulation features are required items for Vietnam service.
This feature works only in Vietnam. Calling it from a country other than Vietnam returns a NOT_SUPPORTED_COUNTRY (31) error.
The struct values delivered via callback (ageRating, message, overlayType, etc.) are for behavior-verification logging purposes. The age-rating image actually shown on the overlay screen must use the resources included in the image pack (ZIP) from Prerequisites.