Skip to content
Stove
Last Updated

STOVE Link

Understanding


STOVE Link is a service that plays a game running on a PC remotely by streaming it in real time to a mobile device.
It plays the real-time-rendered game screen and audio, and sends keyboard, mouse, and touch events from mobile to the PC to control the game directly.

With the STOVE Link SDK, you can easily integrate remote-streaming into a game,
and players can continue a smooth game experience on a mobile device while their PC stays on.



Key Features

STOVE Link is not just screen transmission; it also provides two-way communication and security features for gameplay.

Feature Description
High-quality remote play Supports up to 1080p / 60fps resolution and low-latency streaming of 150ms or less end-to-end.
Two-way input Sends touch, virtual-controller, and virtual-keyboard input from mobile to the PC game in real time.
Game-event notifications Sends key in-game events (item acquisition, low HP, etc.) as mobile push.

  [Remote play]

  [Event notification]



Components

STOVE Link consists of PC, mobile, and the STOVE server infrastructure that relays streaming.

Component Role
STOVE PC client The PC-side entry point that runs the game and toggles streaming mode ON/OFF.
STOVE app The mobile-side entry point. Displays the streaming screen and sends user input to the PC.
STOVE server infrastructure Relays the WebRTC connection between PC and mobile via Signaling / Matchmaker / TURN/STUN servers.



System Components

The system components operating inside the SDK are divided into four.
This structure isn't directly exposed to game code, but it helps in understanding the integration flow.

Component Role
Streaming SDK plugin Embedded in the Unreal/Unity engine to encode game frames and receive input events.
Signaling Server Relays the exchange of WebRTC Offer/Answer and ICE Candidates between PC and mobile.
Matchmaker Server Registers streamable PC sessions and matches them with mobile requests.
TURN / STUN Server Relays media traffic so P2P connections are possible even in NAT environments.



Feature Support by Engine

STOVE Link supports both Unreal Engine and Unity Engine.
The usable LinkSDK version and the games it's applied to differ by engine.

Category Unreal Unity
LinkSDK version v2.0.2 v1.3.6 / v2.0.2
Supported engine version UE 5.4 ~ 5.6 Unity 2022.3.10f1 / Unity 6



How It Works

When a player starts streaming from mobile, a WebRTC session is established through the STOVE server infrastructure.
The game only handles SDK initialization and callback registration; the SDK handles the actual media transmission and input routing.

Step Action Actor
1. Session request Select the game on mobile, then send a streaming request. Player → STOVE App → STOVE Server
2. Matching Look up available PC streamers, then reply to mobile. STOVE Server (Matchmaker)
3. SDK initialization Initialize the PCSDK and StreamingSDK, and start the game process. STOVE App → BaseSDK → Game
4. WebRTC negotiation Exchange Offer/Answer, exchange ICE Candidates, and issue TURN credentials. STOVE App ↔ StreamingSDK ↔ Game
5. Streaming Encode game frames, send them over the WebRTC media channel, and display them on the mobile screen. Game → StreamingSDK → STOVE App → Player

Streaming doesn't include external areas
Areas the game invokes via an external browser or WebView (the billing payment window, external links, in-game WebViews, etc.) are excluded from streaming.
They display and work normally on PC but can't be seen on the mobile streaming screen, so you must handle it to show a separate notice message in-game.



STOVE Link works correctly only when the environment conditions on both PC and mobile are met.

Category Requirement
PC operating system Windows 10 or Windows 11 (64-bit)
PC GPU An NVENC-capable NVIDIA GPU is recommended (AMD/Intel may not be smooth).
Mobile OS Android 10+ / iOS 15+
Streaming quality Up to 1080p / 60fps, end-to-end latency of 150ms or less.
Network Wi-Fi or 5G/LTE. Data usage incurs carrier charges.



Limitations

These are limitations to review in advance before applying STOVE Link.
Most require separate handling in-game, so it's good to reflect them from the planning stage.

Limitation Details
External web pages unsupported External browsers (Chrome, Edge, etc.) and in-game WebViews aren't streamed. In-game notice handling is required.
Concurrent-streaming limit Runnable only per account (not per character). One account and one game can run on only one mobile device.
Game-window minimization (Unreal) The Unreal engine stops rendering in a minimized window, so streaming isn't possible.
PC environment changes Streaming can slow down or stop in sleep mode, screen lock, or hibernation.
Network dependence Real-time data transmission is required, so insufficient network speed causes video stutter or breakup.

Integration Guide



Integration Preparation

PC SDK integration

STOVE Link runs on the STOVE Base SDK.
Before integration, STOVE PC SDK 3.4 or higher must be integrated into the game, and you initialize the STOVELINK SDK after the Base SDK initializes correctly.



Account and authentication info

STOVE Link integration requires per-environment authentication info.
We recommend switching to Live after thoroughly verifying in Sandbox.

Item Description
Environment Two environments provided: Sandbox (SB) / Live.
AppKey A public key for game identification. Issued differently per environment.
AppSecret A secret key for game authentication. Must not be exposed externally.
GameId The unique game ID registered in Partners.

Issuance info can be checked in [the Partners portal], and separate issuance requests are made through the publishing technical contact.



Partners registration

To use STOVE Link, you must register per-game streaming info and notification settings in Partners in advance.
For registration requests, contact the publishing technical contact.

Item Registration details
Apply to use STOVE Link Apply to use STOVE Link in the Partners portal. Register basic info such as Live ON/OFF, game ID, and build version.
Streaming feature settings Set whether OTP, controller, chat, and notifications are used, and the supported resolutions (1080p / 720p / 480p / 360p).
Register the notification key (when using the notification feature) Register the notification message, notification icon, and per-language messages.

  • Partners settings (request from the publishing technical contact)
    • Streaming feature settings

  • Notification-key registration



Basic Integration Flow

It shows a simplified view of the whole flow, from a player selecting a game on PC to streaming to mobile.
You can quickly grasp what mobile, PC, and the server each do at which step.


See the development guide for the detailed flow
The sequence above is the big picture of the whole flow.
Engine-specific concrete steps such as SDK initialization and callback registration can be checked for Unreal and Unity respectively in Development > Development Flow.



Areas invoked via an external browser or WebView in-game aren't shown on the streaming screen, so
while streaming, you need to show a notice message and block the feature.

Exception-handling target Handling method
Billing payment window On clicking payment Confirm, show a "not available during STOVE Link play" notice pop-up.
External link On clicking an External Link such as community, FAQ, or privacy policy, show the same notice pop-up.
In-game WebView On invoking an In-App WebView such as probability info, game notices, or coupon entry, show the same notice pop-up. When not in STOVE Link play, it's shown normally.



  • Exception-handling examples
    • Billing payment window

  • External links (community, FAQ, privacy policy, etc.)

  • In-game WebView (probability info, game notices, coupon entry, etc.)

Recommended notice text
Provide text that lets the user recognize both the current state and the resolution, such as "You are in STOVE Link play. This feature is available after you end STOVE Link play."

Development


SDK Download

Start by downloading the SDK that matches your engine and version. Clicking the file name downloads it directly, and the latest change history can be checked in the release notes.

Engine SDK file Supported environment Version
Unity STOVELINK_Unity_1.3.6.unitypackage Unity 2022.3 v1.3.6
Unity STOVELINK_Unity_2.0.2.unitypackage Unity 6 v2.0.2
Unreal LINKSDK_v.3.0.2_UNREAL_v5.6.zip UE 5.4 ~ 5.6 v3.0.0

Order after downloading
After getting the SDK, check the environment requirements in Prerequisites and follow the per-engine steps in Development Flow.

Prerequisites

Before applying the STOVE Link SDK to your code, the Integration Guide > Integration Preparation step must be complete, and you must meet the environment requirements below depending on your engine.


  • Unreal environment requirements
    Item Details
    Unreal Engine UE 5.4 ~ 5.6 (the current LinkSDK v3.0.0 is based on UE 5.6)
    Development environment Visual Studio 2022, .NET Framework 4.8, DirectX
    Target OS Windows 10 / 11 (x64)
    WebRTC M96 ~ M109 compatible
    BaseSDK (PCSDK) v3.4 or higher
    Recommended specs Intel Core i5 or higher / NVIDIA GTX 1060 or higher / RAM 16GB or higher
    Project type Both C++ projects and Blueprint projects are supported

  • Unity environment requirements
    Item Details
    Unity version Unity 2022.3.10f1 or higher (2022.3.22f1 recommended) or Unity 6
    - For Unity 2022.3: STOVELINK_Unity_1.3.6
    - For Unity 6: STOVELINK_Unity_2.0.2
    Development environment Visual Studio 2019 or higher, C# Scripts
    Target OS Windows 10 / 11 (x64)
    Scripting Backend IL2CPP
    Required Unity Package Input System (1.7.0 or higher)
    ※ If an existing Input System package is installed, we recommend removing it once and reinstalling to use the one from the STOVELINK package.
    WebRTC com.unity.webrtc 3.0.0-pre8 (managed automatically inside the Unity SDK)

Development Flow


Unreal

  • Step 1. Install the plugin
    Item Details
    Plugin copy location YourProject/Plugins/STOVELINK/
    Run the initialization script Run RunMeFirst.bat in the plugin folder once to copy dependency files.
    For C++ projects Right-click the .uproject file → run Generate Visual Studio project files to refresh the IDE project.

  • Step 2. Enable the plugin Choose one of two activation methods.

  • Method A. Enable in the Unreal Editor
    1. Launch the Editor and go to the Edit → Plugins menu
    2. Disable the built-in Pixel Streaming plugin
    3. Enable the STOVE Streaming plugin
    4. Restart the Editor

Pixel Streaming must be disabled.
If both plugins are enabled at once, a conflict occurs and streaming won't work correctly.


  • Method B. Edit the .uproject file directly
    json
    "Plugins": [
      {
        "Name": "PixelStreaming",
        "Enabled": false
      },
      {
        "Name": "STOVELINK",
        "Enabled": true
      }
    ]
    



  • Step 3. Verify BaseSDK initialization STOVE Link works only after BaseSDK initialization succeeds. At game initialization, be sure to check that IsSuccessful() is true in the BaseSDK Base_Initialize callback.


  • Step 4. Add dependencies and initialize the SDK The approach differs between C++ projects and Blueprint projects.

  • C++ project Add dependencies to YourProject.Build.cs.
    csharp
    // 1) ThirdParty path
    string ThirdPartyPath = Path.Combine(
        PluginDirectory, 
        "../../Plugins/STOVELINK/ThirdPartyLibrary/StovePCSDK/BaseSDK/Deploy"
    );
    // 2) Link the BaseSDK library
    PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "BaseSDK.lib"));
    RuntimeDependencies.Add(Path.Combine(ThirdPartyPath, "BaseSDK.dll"));
    // 3) Add the STOVELINK module dependency
    PublicDependencyModuleNames.AddRange(new string[] { "STOVELINK" });
    

    Call STOVE Link initialization in the Base_Initialize callback.
    cpp
    void AYourGameMode::HandleBaseInitialize(const FBaseInitResult& Result)
    {
        if (!Result.IsSuccessful()) return;
        // Initialize STOVE Link
        UStoveLinkSubsystem::Link_Initialize();
    }
    

  • Blueprint project Connect the following nodes in order in the Blueprint event graph.
    • Event Begin PlayLink Initialize (Blueprint node)
    • Link Set On Player Connected / Link Set On Player Disconnected (register callbacks)
    • Call Link Set Bitrate, Link Toggle Mobile Virtual Keyboard, Link Send Mobile Notify, etc. as needed

    For the streaming component, add USTOVELINKStreamerComponent to the actor and bind the OnStreamStarted / OnStreamStopped events to use it.



  • Step 5. Register callbacks and call features Handle add-on features such as streaming-state changes, mobile input, and notification sending on a callback basis. The available functions are as follows. (see the API reference menu for detailed specs)
    Feature When to use and recommended handling
    Link_IsStreamingEnabled Check whether the STOVE Link feature is enabled by game policy.
    If disabled, enter the normal local-play path.
    Link_IsStreaming Check whether there's a current real-time streaming connection with mobile.
    Used for branching mobile-only UI.
    Link_SetBitrate Dynamically adjust the video bitrate.
    Recommended values: low 1Mbps · normal 3Mbps · high 5Mbps · ultra-high 10Mbps.
    Link_ToggleMobileVirtualKeyboard Show/hide the mobile virtual keyboard when an in-game text input field is focused.
    Works only while streaming is connected.
    Link_SetOnReceiveUIText Register the callback to handle mobile input text delivered to the game.
    Depending on the enableSetReceivedText option, it auto-sets the last focused widget or only calls the callback.
    Link_SendMobileNotify Send game events (item acquisition, character death, etc.) as mobile-app notifications.
    Requires the notification key and variable mapping pre-registered in Partners.
    Link_SetOnPlayerConnected A callback for when the mobile client connects.
    Used to enable streaming-only UI.
    Link_SetOnPlayerDisconnected A callback for when the mobile client disconnects.
    Used for follow-up handling such as pausing gameplay.

Link_SetOnReceiveUIText overwrites the existing callback.
Registering the same callback twice invalidates the previous registration. Register it in only one place across the game, or manage the dispatch logic yourself inside the callback.



  • Step 6. Build and verify After building, check that the following log is output.
    text
    STOVELINK runtime initialized (Streaming Enabled = true)
    

    It's normal for the STOVELINK module folder to be created under YourProject/Intermediate/Build/Win64/.



  • Step 7. v2 → v3 migration (if applicable) Projects using existing v2 code handle the following when upgrading to v3.

  • What can be kept
    • #include "STOVELINKSdk.h" can be used as-is. (the STOVELINK namespace is kept as an Alias of LINKSDK.)
    • Existing function-call code compiles without changes.

  • Required changes Change the module-dependency references in .uproject and *.Build.cs.
    csharp
    // AS-IS (v2)
    PublicDependencyModuleNames.AddRange(new string[] { "STOVELINK" });
    
    // TO-BE (v3)
    PublicDependencyModuleNames.AddRange(new string[] { "PixelStreaming" });
    



Unity

  • Step 1. Install the package
    1. Download the .unitypackage matching your Unity version from the SDK download page
    2. Import the package via Assets → Import Package → Custom Package in the Unity Editor
    3. If the Input System package is already installed at import, we advise removing the existing Input System first to avoid conflicts and using the one from the STOVELINK package



  • Step 2. Multi-platform preprocessing The STOVE Link SDK works only on the Windows Standalone runtime. Wrap all SDK calls with preprocessor directives so they're ignored without compile errors on other build targets such as Editor, mobile, and Linux.
    csharp
    #if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
        // STOVE Link SDK call code
    #endif
    



  • Step 3. Initialize the SDK and the log After BaseSDK initialization, initialize the STOVE Link SDK and the log feature in sequence.
    csharp
    #if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
        // 1) Confirm BaseSDK initialization completed (PCSDK3 callback)
        // 2) Initialize the STOVE Link SDK
        SignalingManager.Initialize();
        
        // 3) Initialize log collection (recommended for debugging in production)
        SignalingManager.InitializeLogger();
    #endif
    



  • Step 4. Enable Remote Control If the game already uses the Unity Input System, it's automatically compatible. If you use the existing UI (uGUI), you need to replace the EventSystem's input module.
    Input system in use Handling method
    Unity Input System If a Warning pop-up appears at package import, choose Yes and restart the Editor.
    Existing Unity UI (uGUI) On the scene's EventSystem GameObject, click Replace with InputSystemUIInputModule on the Standalone Input Module.


  • Step 5. Streaming connection-state callbacks and exception handling Receive the mobile connect/disconnect points and branch the game UI. Also, some screens during streaming (the billing payment window, external links, in-game WebViews) don't work correctly in the mobile environment, so separate exception handling is recommended.
    csharp
    #if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
        SignalingManager.OnStreamingConnect += OnStreamingConnect;
        SignalingManager.OnStreamingDisconnect += OnStreamingDisconnect;
    #endif
    
    void OnStreamingConnect()
    {
        // Mobile connected — enable mobile-only UI
    }
    
    void OnStreamingDisconnect()
    {
        // Mobile disconnected — pausing the game is recommended
    }
    
    bool IsPlayerConnected()
    {
    #if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
        return SignalingManager.IsStreamingEnabled() != PARAM_SETTER.NONE;
    #else
        return false;
    #endif
    }
    

Block the billing payment window, external links, and in-game WebViews in the mobile streaming environment.

Unlike PC, the mobile client can't render external-browser calls or payment UI correctly.
When entering such a screen, we recommend judging with IsPlayerConnected() and redirecting to a PC-environment notice message.



  • Step 6. Add-on features (notifications · virtual keyboard · virtual controller)

  • Send notifications to the mobile app (SendGameNotify) Send game events as mobile-app notifications. Use the notification key and variable mapping pre-registered in Partners.
    csharp
    var payload = "{ \"message1\": \"Holy Knight\", \"message2\": \"Legendary\", \"message3\": \"Distorted Nightmare Trajectory Heavy Gauntlet\" }";
    signalingManager.SendGameNotify(integrationKey, payload, (statusCode) => {
        // Use the result code only for logging. Handle it so it doesn't affect gameplay.
    });
    

    Even if the notification API call fails, it must not affect game progress. We recommend only logging, without showing a separate error message. See the API reference menu for error-code details.

  • Using the virtual keyboard (CommandMsg.OnReceiveText) When text input is needed during streaming, receive text entered on the mobile keyboard into the game UI and handle it.
    csharp
    #if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
        CommandMsg.OnReceiveText += CommandMsg_OnReceiveText;
    #endif
    
    void CommandMsg_OnReceiveText(string text)
    {
        // Reflect the text in the currently selected InputField
        GameObject obj = EventSystem.current.currentSelectedGameObject;
        if (obj.GetComponent<InputField>() != null)
        {
            obj.GetComponent<InputField>().text = text;
        }
        else if (obj.GetComponent<TMP_InputField>() != null)
        {
            obj.GetComponent<TMP_InputField>().text = text;
        }
    }
    

  • Control virtual-controller display from the mobile app (CommandMsg.OnShowVirtualController) When the controller is turned on/off in the mobile app's link options, the game receives a callback and toggles the on-screen virtual-controller UI. The UI-toggle logic must be implemented by the game itself.
    csharp
    #if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
        CommandMsg.OnShowVirtualController += OnShowVirtualControllerCallback;
    #endif
    
    void OnShowVirtualControllerCallback(bool isShow)
    {
        // Sample: toggle the virtual-controller Canvas activation
        var controller = GameObject.Find("UI_Canvas_StarterAssetsInputs_Joysticks");
        var canvas = controller.GetComponent<Canvas>();
        canvas.enabled = isShow;
    }
    



  • Step 7. Remove the SDK (if needed) There are two ways to remove the STOVE Link SDK from the project.
    Method Procedure
    Stable removal Remove all STOVELINK-related packages in the Unity Package Manager, then manually delete the STOVELINK folder under Assets/StreamingAssets/.
    Quick removal Run the delete_package.bat file included in the SDK package in PowerShell. If the NEW icon appears in the package list on re-import, removal succeeded.

Testing and Verification

After integration is complete, test in the order Sandbox (SB) → Live. Whitelist registration for the test-target game is required. (request registration from the publishing technical contact)

Step Test content Category
1. PC client Download and install the client for the Sandbox (SB) / Live environment. STOVE PC Client
2. Game install and build registration Upload the development build to Partners, then install and run the game with the PC client.
(upload a new build to Partners whenever the build updates)

The game must be run with STOVE Link use (ON) set.
-
3. Install the STOVE app After installing and running the STOVE app, log in to the STOVE app with the account logged in on the PC client
Android - install the latest test app.
Download APK (SB)
Download APK (Live)
iOS - install via TestFlight or a QR code.
- Live: TestFlight

- Live: use a QR code
Download APK (SB)
TestFlight(Live)
4. Play test - Whether input (touch controls) responds correctly
- Whether the sound, notification, controller, resolution, and virtual-keyboard toggles in the options panel work correctly
- Whether the mobile app receives notifications and shows multilingual messages correctly when notifications are sent
- Whether the game-side callbacks are called correctly on disconnect/reconnect
-

Note
The Sandbox (SB) environment is usable only on the Smilegate internal network.

Troubleshooting

  • Environment / execution checks
    • 1) The log file isn't created
      • Check whether StoveLink-related logs are created under the %appdata% path.
      • If the user-folder path contains Korean, log creation can fail. Move the user environment to an ASCII-character path or test on a separate user account.



    • 2) The streaming button is disabled in the STOVE launcher Check whether the enable_linkplay option is enabled in the launcher policy settings file.
      text
      Path: C:\Users\{UserName}\AppData\Local\STOVE{Env}\Config\policyConfig.json
      
      json
      {
        "stove_launcher_policy_config": {
          "enable_linkplay": true
        }
      }
      



    • 3) If the LinkPlay feature is disabled If LinkPlay display is disabled for a specific game, you can temporarily bypass it by registering the game ID directly in the per-user PersonalConfig.json. It applies only after you restart the STOVE launcher following the edit.
      text
      Path: C:\Users\<UserName>\AppData\Local\STOVEGATE8\Config\<MemberNumber>\PersonalConfig.json
      
      json
      {
        "streamingGameIds": ["<GameID>"]
      }
      



    • 4) I want to check the member number You can check the member number in the WebSocket connection log inside the log file. In the example, 108195073 is the member number. You can also check it on the STOVE profile page.
      text
      [DBG] Signaling: Connecting WS wss://stovelink-ss.gate8.com:8888/s/108195073-1
      



  • Network checks
    • 5) Check the CDN connection Check whether the following CDN-request success message is in the log. If that log is missing, check the firewall/network settings and whether a VPN/proxy is blocking it.
      text
      BaseAPIRequest: https://static-resource.gate8.com/.../config_streaming.json HTTP request successfully (OK)
      



    • 6) Check the WebSocket connection On a normal connection, the following log is output. If that log is missing, check the network environment, whether security software is blocking it, and the settings file.
      text
      [DBG] Signaling: WS connected.
      



  • Feature-specific issues
    • 7) Audio isn't output in a specific scene A sound-related instance must be created before STOVE Link initialization. Start the audio system first at game initialization, then call STOVE Link initialization.

In Unreal, calling FApp::SetUnfocusedVolumeMultiplier(1.0f); before STOVE Link initialization keeps streaming audio even if the game loses focus. (auto-call was removed in v1.2.9)


  • 8) A crash occurs on mobile-keyboard invocation when using custom UI rather than UMG Automatic keyboard invocation has been disabled since LinkSDK v1.2.5. On the CP (game) side, use the API that invokes the keyboard manually (Link_ToggleMobileVirtualKeyboard).



  • 9) Unreal 5.6 builds don't build in the Debug, DebugGame, or Test configuration The missing build configurations were supplemented in LinkSDK v2.0.2 (2026-01-26 build). Please update to the latest SDK.



  • 10) Input System package conflicts occur in Unity If the Input System package is already installed in an existing project, it can conflict with the one from the STOVELINK package. Remove the existing Input System, reinstall the one from the STOVELINK package, and restart the Editor.



  • 11) A Unity package conflict reverts the WebRTC version to 3.0.0-pre7 Resolved in Unity SDK v1.3.6 or higher. Updating the SDK to the latest version keeps 3.0.0-pre8.

See the API reference menu for the detailed meaning of response codes and error codes.
The full list of HTTP Status Codes and Error Codes returned by the notification API, streaming callbacks, etc. is managed in a separate menu.

Sample Code

  • Unreal C++ — from initialization to add-on features A sample composed as one flow: Base_Initialize callback → STOVE Link initialization → callback registration → notification sending.
cpp
// YourGameMode.h
#include "STOVELINKSdk.h"

UCLASS()
class YOURGAME_API AYourGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:
    virtual void BeginPlay() override;

private:
    void HandleBaseInitialize(const FBaseInitResult& Result);
    void OnPlayerConnected(FString StreamerId, FString PlayerId, bool bQualityController);
    void OnPlayerDisconnected(FString StreamerId, FString PlayerId, bool bQualityController);
    void OnReceiveUIText(FString TextReceived);

    void NotifyAchievementUnlocked(const FString& AchievementName);
};
cpp
// YourGameMode.cpp
void AYourGameMode::BeginPlay()
{
    Super::BeginPlay();

    // Register the BaseSDK initialization callback (PCSDK3 area)
    // For the example, assume it's registered externally as RegisterInitCallback.
    BaseSDK::SetOnInitialize([this](const FBaseInitResult& Result) {
        HandleBaseInitialize(Result);
    });
}

void AYourGameMode::HandleBaseInitialize(const FBaseInitResult& Result)
{
    if (!Result.IsSuccessful())
    {
        UE_LOG(LogTemp, Warning, TEXT("BaseSDK init failed. Skip STOVELINK init."));
        return;
    }

    // 1) Initialize the STOVE Link SDK
    UStoveLinkSubsystem::Link_Initialize();

    // 2) Check whether the streaming feature is enabled
    if (!UStoveLinkSubsystem::Link_IsStreamingEnabled())
    {
        UE_LOG(LogTemp, Log, TEXT("STOVELINK disabled by policy. Local play only."));
        return;
    }

    // 3) Register callbacks
    UStoveLinkSubsystem::Link_SetOnPlayerConnected(
        [this](FString S, FString P, bool Q) { OnPlayerConnected(S, P, Q); }
    );
    UStoveLinkSubsystem::Link_SetOnPlayerDisconnected(
        [this](FString S, FString P, bool Q) { OnPlayerDisconnected(S, P, Q); }
    );

    // 4) Virtual-keyboard input callback (includes the option to auto-reflect in the last focused widget)
    UStoveLinkSubsystem::Link_SetOnReceiveUIText(
        [this](FString Text) { OnReceiveUIText(Text); },
        /* enableSetReceivedText */ true
    );

    // 5) Set the initial bitrate (3Mbps)
    UStoveLinkSubsystem::Link_SetBitrate(3000000);
}

void AYourGameMode::OnPlayerConnected(FString StreamerId, FString PlayerId, bool bQualityController)
{
    // Mobile client connected — enable mobile-only UI
}

void AYourGameMode::OnPlayerDisconnected(FString StreamerId, FString PlayerId, bool bQualityController)
{
    // Mobile client disconnected — follow-up handling such as pausing the game
}

void AYourGameMode::OnReceiveUIText(FString TextReceived)
{
    // Use only when you want extra handling in the callback alone
    UE_LOG(LogTemp, Log, TEXT("Mobile keyboard text received: %s"), *TextReceived);
}

void AYourGameMode::NotifyAchievementUnlocked(const FString& AchievementName)
{
    const FString IntegrationKey = TEXT("game.achievement.unlocked");
    const FString Payload = FString::Printf(
        TEXT("{ \"message1\": \"%s\" }"), *AchievementName
    );
    const FString LangCode = TEXT("ko");

    UStoveLinkSubsystem::Link_SendMobileNotify(
        IntegrationKey,
        Payload,
        LangCode,
        [](int32 StatusCode) {
            // Only log so it doesn't affect game progress
            UE_LOG(LogTemp, Log, TEXT("SendMobileNotify result: %d"), StatusCode);
        }
    );
}

  • Unreal Blueprint — node composition guide In a Blueprint-based project, you can compose the same flow with the following pattern.
text
[Event Begin Play]
   └─→ [Link Initialize]
         └─→ [Branch: Link Is Streaming Enabled]
               ├─ True  → [Link Set On Player Connected]   (bind Custom Event)
               │         → [Link Set On Player Disconnected]
               │         → [Link Set On Receive UI Text]
               │         → [Link Set Bitrate (3000000)]
               │         → [Setup Streaming UI]
               └─ False → [Show Local Play Only Message]

[Custom Event: OnAchievementUnlocked (Name: String)]
   └─→ [Make JSON: {"message1": Name}]
         └─→ [Link Send Mobile Notify]
               └─→ [Branch: Status Code == 0]
                     ├─ True  → [Log: "Notify sent"]
                     └─ False → [Log: "Notify failed (silent)"]

For the streaming component, add USTOVELINKStreamerComponent to the actor and bind the OnStreamStarted · OnStreamStopped events to handle it.


  • Unity C# — from initialization to add-on features
csharp
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using TMPro;
using StoveLink;

public class StoveLinkBootstrap : MonoBehaviour
{
    [SerializeField] private GameObject virtualControllerCanvas;

    private void Start()
    {
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
        // 1) Assume BaseSDK initialization is already complete in the PCSDK3 area
        
        // 2) Initialize the STOVE Link SDK + log
        SignalingManager.Initialize();
        SignalingManager.InitializeLogger();

        // 3) Check the activation policy
        if (SignalingManager.IsStreamingEnabled() == PARAM_SETTER.NONE)
        {
            Debug.Log("STOVELINK disabled by policy. Local play only.");
            return;
        }

        // 4) Register connection-state callbacks
        SignalingManager.OnStreamingConnect += OnStreamingConnect;
        SignalingManager.OnStreamingDisconnect += OnStreamingDisconnect;

        // 5) Virtual-keyboard input callback
        CommandMsg.OnReceiveText += OnReceiveText;

        // 6) Virtual-controller display-control callback
        CommandMsg.OnShowVirtualController += OnShowVirtualController;
#endif
    }

#if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
    private void OnStreamingConnect()
    {
        // Mobile connected — enable streaming-only UI
    }

    private void OnStreamingDisconnect()
    {
        // Mobile disconnected — pausing the game is recommended
    }

    private void OnReceiveText(string text)
    {
        GameObject obj = EventSystem.current.currentSelectedGameObject;
        if (obj == null) return;

        if (obj.GetComponent<InputField>() != null)
        {
            obj.GetComponent<InputField>().text = text;
        }
        else if (obj.GetComponent<TMP_InputField>() != null)
        {
            obj.GetComponent<TMP_InputField>().text = text;
        }
        Debug.Log($"Mobile keyboard text received: {text}");
    }

    private void OnShowVirtualController(bool isShow)
    {
        if (virtualControllerCanvas == null) return;
        var canvas = virtualControllerCanvas.GetComponent<Canvas>();
        canvas.enabled = isShow;
    }

    // Notification method to be called externally
    public void NotifyAchievementUnlocked(string achievementName)
    {
        string integrationKey = "game.achievement.unlocked";
        string payload = $"{{ \"message1\": \"{achievementName}\" }}";

        SignalingManager.Instance.SendGameNotify(
            integrationKey,
            payload,
            (statusCode) => {
                // Only log so it doesn't affect game progress
                Debug.Log($"SendGameNotify result: {statusCode}");
            }
        );
    }
#endif

    private void OnDestroy()
    {
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
        SignalingManager.OnStreamingConnect -= OnStreamingConnect;
        SignalingManager.OnStreamingDisconnect -= OnStreamingDisconnect;
        CommandMsg.OnReceiveText -= OnReceiveText;
        CommandMsg.OnShowVirtualController -= OnShowVirtualController;
#endif
    }
}

You can copy the sample code as-is, but adjust the callback registration and cleanup timing to fit your game structure.
In particular, callbacks must be released at OnDestroy or scene transition to prevent memory leaks and duplicate calls.

Frequently Asked Questions



Q1. Which engine can I use it in, Unreal or Unity?
A. Both are supported.
Unreal uses LinkSDK v2.0.2 / v3.0.0 on UE 5.4~5.6, and Unity uses LinkSDK v1.3.6 / v2.0.2 in the 2022.3 / Unity 6 environments.
The applied games and recommended SDK versions differ by engine, so check the download links in the Prerequisites step.
Q2. Does it work on AMD or Intel GPUs too?
A. It can work but isn't recommended.
STOVE Link is designed around NVIDIA GPUs' NVENC hardware-accelerated video encoding, so smooth streaming can be difficult on AMD/Intel GPUs.
The list of supported NVIDIA GPUs can be checked in the Pixel Streaming official documentation.
Q3. When should I call STOVELINK SDK initialization?
A. It must be called after the STOVE Base SDK initializes correctly.
On Unreal, call STOVELINK::Link_Initialize() after confirming IsSuccessful() == true in the Base_Initialize callback; on Unity, call STOVELINK.RenderStreaming.CreateAutomaticStreaming() after View_Initialize and IAP_Initialize.
If you don't follow the initialization order, the streaming feature won't be enabled.
Q4. How can the game tell whether it's streaming?
A. Combine two APIs.
Link_IsStreamingEnabled() returns whether the streaming feature is enabled by build/settings, and Link_IsStreaming() returns whether a WebRTC session is actually active right now.
To check whether a player is connected from mobile, register the OnPlayerConnected / OnPlayerDisconnected callbacks or poll with GetIsPlayerConnected().
Q5. Why can't external links or in-game WebViews be streamed?
A. STOVE Link encodes frames rendered by the game engine on the GPU and transmits them.
External browsers (Chrome, Edge, etc.) and in-game WebViews operate outside the game engine's rendering pipeline, so they aren't included in the streaming screen.
To reduce user confusion, we recommend blocking the feature and showing a notice pop-up while streaming.
Q6. What value should I set the bitrate to?
A. The recommended bitrates are low 1Mbps, normal 3Mbps, high 5Mbps, and ultra-high 10Mbps.
You can adjust it dynamically with Link_SetBitrate(UINT Bitrate), and it's good to design the game to switch automatically based on the user's network environment (Wi-Fi / 5G/LTE).
Since a bitrate change entails an encoder reset, we recommend not calling it too often.
Q7. How does the game notification (SendGameNotify) relate to push permission?
A. Even with the STOVE app's push reception OFF, the notification message can be checked in the app's notification box.
However, if the user has disabled notifications at the STOVE-account level, -4046 (User notification is inactive) is returned.
Also check whether integrationKey matches the alarm key registered in Partners, and whether the message is registered for the registered language code (ko / zh-tw / en, etc.).
Q8. Can I stream simultaneously on multiple mobile devices with one account?
A. One account can start/end streaming on multiple mobile devices, but the same game can be played simultaneously on only one mobile device.
Duplicate streaming isn't possible, and it runs per account, not per character.
Q9. What do I need to change when migrating from v2 to v3?
A. STOVELINK is designated as an Alias of LINKSDK, so existing #include "STOVELINKSdk.h" and STOVELINK-namespace call code mostly compile as-is.
However, the dependency references in the .uproject file and *.Build.cs files must be updated from STOVELINK to PixelStreaming.
Change both the Plugin Name and the module dependencies, then rebuild the project.
Q10. How do I test the Sandbox and Live environments separately?
A. Sandbox uses a PC client and STOVE app accessible only on the Smilegate internal network.
Live-environment testing uses the official STOVE PC client and STOVE app; on iOS you install the beta app via TestFlight, and on Android from a separate APK download page.
Whitelist registration requires a prior request to the SGP contact.



Need to contact us directly? stove.developers@smilegate.com