Skip to content

Unity Quick Start

This Quick Start covers:

  • IGP.UnitySDK is already installed in the project
  • IGPRuntimeManager is present in the scene
  • Only appId is required up front
  • Your game startup flow explicitly calls IGPRuntimeManager.InitializeAsync()
  • For single-player or non-room integrations, validate desktop capabilities first (game authorization and achievements)
  • For multiplayer integrations, use startup information injected by the IGP desktop client to validate join room -> ready -> realtime

In other words, this page gives you entry points for both desktop capabilities and the room flow, but they do not share the same prerequisites. A game that does not integrate multiplayer rooms does not need to create a room, choose a map, become ready, send realtime messages, or connect KCP. If your first goal is to prove the multiplayer path, you do not need to finish achievement setup first.

  • cn.indiegp.sdk.unity is already installed by following Unity Installation
  • You have an appId provided by IGP operations
  • The IGP desktop client is installed and runnable on the local machine (Windows 10+)

Create Assets/Scripts/IGPQuickstartDriver.cs in your project:

using System;
using UnityEngine;
using IGP.UnitySDK;
using IGP.UnitySDK.Models;
public sealed class IGPQuickstartDriver : MonoBehaviour
{
[SerializeField] private IGPRuntimeManager runtimeManager;
[SerializeField] private string debugMessageType = "quickstart_ping";
[SerializeField] private string unlockAchievementKey = "first_session";
[SerializeField] private string progressAchievementKey = "matches_played";
private void Awake()
{
runtimeManager ??= FindObjectOfType<IGPRuntimeManager>();
}
private void OnEnable()
{
if (runtimeManager == null)
{
Debug.LogError("[IGP Quickstart] IGPRuntimeManager is missing.");
enabled = false;
return;
}
runtimeManager.onRoomJoined.AddListener(HandleRoomJoined);
runtimeManager.onMessageReceived.AddListener(HandleMessageReceived);
runtimeManager.onError.AddListener(HandleError);
}
private async void Start()
{
var ok = await runtimeManager.InitializeAsync();
if (!ok)
{
Debug.LogError("[IGP Quickstart] SDK initialization failed.");
}
}
private void OnDisable()
{
if (runtimeManager == null) return;
runtimeManager.onRoomJoined.RemoveListener(HandleRoomJoined);
runtimeManager.onMessageReceived.RemoveListener(HandleMessageReceived);
runtimeManager.onError.RemoveListener(HandleError);
}
[ContextMenu("IGP/Send Quickstart Message")]
public async void SendQuickstartMessage()
{
if (runtimeManager == null) return;
await runtimeManager.SendMessageAsync(new Message
{
type = debugMessageType,
roomId = runtimeManager.CurrentRoomId,
playerId = runtimeManager.PlayerId,
reliable = true,
content = new
{
text = "hello from quickstart",
sentAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
}
});
Debug.Log("[IGP Quickstart] Sent realtime message.");
}
[ContextMenu("IGP/Unlock Achievement")]
public async void UnlockAchievement()
{
if (runtimeManager == null) return;
var result = await IGPSDK.UnlockAchievementAsync(runtimeManager, unlockAchievementKey);
Debug.Log($"[IGP Quickstart] Unlock success={result.success}, duplicated={result.duplicated}");
}
[ContextMenu("IGP/Report Achievement Progress")]
public async void ReportAchievementProgress()
{
if (runtimeManager == null) return;
var result = await IGPSDK.ReportAchievementProgressAsync(
runtimeManager, progressAchievementKey, 1, "quickstart_manual");
Debug.Log($"[IGP Quickstart] Progress success={result.success}, duplicated={result.duplicated}");
}
private async void HandleRoomJoined(Room room)
{
Debug.Log($"[IGP Quickstart] Joined room id={room.id}, code={room.code}");
await runtimeManager.SetReadyAsync(true);
Debug.Log("[IGP Quickstart] Local player marked ready.");
}
private void HandleMessageReceived(string messageType, object content)
{
Debug.Log($"[IGP Quickstart] Message type={messageType}, payload={content}");
}
private void HandleError(string error)
{
Debug.LogError($"[IGP Quickstart] Runtime error: {error}");
}
}

2. Add the runtime components in the scene

Section titled “2. Add the runtime components in the scene”
  1. Create an empty object such as IGPBootstrap
  2. Add these components:
    • IGPRuntimeManager
    • IGPQuickstartDriver
  3. Assign IGPQuickstartDriver.runtimeManager to the IGPRuntimeManager on the same object
  4. If your game changes scenes and you do not want the session to break, keep this object alive across scenes and make sure there is only one IGPRuntimeManager

After you add IGPRuntimeManager, the SDK automatically assigns the project’s IGPConfig. If the project does not have one yet, it creates Assets/IGP/IGPConfig.asset.

Fill in the appId assigned by IGP operations on IGPConfig.

The SDK does not start just because IGPRuntimeManager exists in the scene. Call InitializeAsync() from your game startup flow.

Choose the validation path that matches your integration target.

If you only integrate game authorization, achievements, or other room-independent desktop capabilities, start with the “desktop-client-only capabilities” path in Unity Debugging.

The minimum target is to see:

  1. InitializeAsync() succeeds
  2. a successful log after manually triggering Unlock Achievement or Report Achievement Progress

This path does not require room creation, map selection, ready, realtime messaging, or KCP.

If your game integrates rooms, realtime messaging, state, RPC, Mirror Transport, KCP, or runtime map changes, use the “full hosted room flow” path in Unity Debugging.

The minimum target is to see:

  1. a Joined room log
  2. a Local player marked ready log
  3. a send log after you manually trigger Send Quickstart Message

If this part is not working yet, do not mix room debugging and achievement debugging together.

5. Add desktop capability validation only if you need it

Section titled “5. Add desktop capability validation only if you need it”

If you also want to validate game authorization or achievements inside Unity Editor, then add the extra setup from the “desktop-client-only capabilities” path in Unity Debugging.

You usually do not need to fill Desktop Executable Path Debug Override. If this path is empty, the SDK launches the desktop client for the selected environment and sends the Unity Editor process path together with the appId; the desktop SDK debugging rules decide whether the attach is allowed. Fill this path only when you need to simulate an installed game executable or debug local executable binding. In that case, use the real Windows executable path of the game, not the desktop client path.

This is not the desktop client path. The SDK finds the matching desktop client from SDK Environment: PROD launches IndieGamesPass, PREVIEW launches IndieGamesPass Preview, and DEV launches IndieSpark. In PROD and PREVIEW, the SDK only starts the matching official trusted desktop client; explicit Desktop Launch Command or INDIEGP_DESKTOP_PATH overrides are for DEV debugging setups.

Once that extra setup is in place, manually trigger:

  • Unlock Achievement
  • Report Achievement Progress

Treat acceptance as separate blocks based on the integration target:

  1. appId is configured
  2. InitializeAsync() succeeds
  3. game authorization or achievement calls return the expected result
  1. Joined room appears in the logs
  2. Local player marked ready appears in the logs
  3. You see a send log after manually triggering Send Quickstart Message
  1. You see a successful log after manually triggering Unlock Achievement
  2. Or you see a successful log after manually triggering Report Achievement Progress

After Quick Start is complete, continue based on the target feature: