Skip to main content

Quick Integration of PC SDK

It is recommended to refer to the source code of the Demo project when reading this part of the content

1 Obtain Credentials​

Integrating the SDK requires first creating an application in the minigame host Console, obtaining the APP KEY, APP SECRET, and Service Token specific to each application.

When starting the SDK, initialization is required through APP KEY, APP SECRET. The accessing party can also contact Unity to create App Service Token / App Key / App Secret.

The following is an example of test App Service Token / App Key / App Secret

  • App Service Token

  • App Key: AKIDt1vMSYVFf1twI53iDecobx6QsTK0

  • App Secret: ufzN1iD8PsnMW0ViDCMhpJFBiLR1E1Xf

Service Token is mainly used to call the following API to obtain the game list, from which Game ID can be retrieved to start the game.

Use a token to obtain a list of minigames ​

The platform can use the server token to obtain the list of minigames of the host application.

Example of request:

GET /api/game/list?appId={appId} HTTP/1.1
Host: minihost.tuanjie.cn
Authorization: Bearer {service_token}

Request Parameter Description:

ParameterDescription
appIdHost Application ID
AuthorizationServer token, formatted as Bearer {service_token}

Response Example:

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"id": "67b*********************",
"appId": "67b*********************",
"name": "name",
"briefIntro": "briefIntro",
"gameType": "weixinminigame",
"iconUrl": "https://minihost.cdn.tuanjie.cn/game_app/67b6eb506ffcda2559ecd19d/app_icon/********.png",
"launchKey": "67b*********************",
}
]

Response field description:

FieldDescription
idGame ID
appIdHost Application ID
nameGame Name
briefIntroGame Introduction
gameTypeGame Type
iconUrlGame Icon URL
launchKeyThe return value here is the game ID

In a real production environment, Service Token should be used on the server side, and the above API should be called from the server. In the Demo project, Service Token is used on the Client side, which is just an example and not recommended for use in a production environment.

2 Import SDK​

  • SDK supports Windows 10+ / macOS 10.15+

  • Add webglhost-sdk-1.0.0.tgz and webglhost-runtime-pc-1.0.0.tgz to the project.

Install dependencies:

npm install ./webglhost-sdk-1.0.0.tgz ./webglhost-runtime-pc-1.0.0.tgz

Or add in package.json:

{
"dependencies": {
"@webglhost/sdk": "file:./webglhost-sdk-1.0.0.tgz",
"webglhost-runtime-pc": "file:./webglhost-runtime-pc-1.0.0.tgz",
"electron": "^36.0.0"
}
}

Import Modules:

const { TJHostHandle, RuntimeGameHandle, TJConstants } = require('webglhost-runtime-pc');

3 Initialize the SDK​

Initialize TJHostHandle within the Host SDK. Subsequent game control-related APIs depend on this instance. You can determine whether the initialization was successful by checking if the return value of TJHostHandle.initialize is null.

function initTJHostHandle() {
// AKIDcv9N9wkDXKZ7gDoB2avKlu0N8tnS is a test [Demo App Key]
// sp9ZsGlNLmTSX9o0sa29C5FwmxemUV8A is a test [Demo App Secret]
TJHostHandle.initialize('AKIDcv9N9wkDXKZ7gDoB2avKlu0N8tnS', 'sp9ZsGlNLmTSX9o0sa29C5FwmxemUV8A', (hostHandle, error) => {
if (!hostHandle) {
return;
}

// End of hostHandle initialization
});
}

4 Launch a single-instance game​

4.1 Create Host​

Create and initialize a RuntimeGameHandle using an instance initialized with TJHostHandle, which operates throughout the lifecycle of the minigame.

async function initGameHandle() {
const gameHandle = await hostHandle.createGameHandle();

// end of RuntimeGameHandle initialization
return gameHandle;
}

4.2 Set game startup parameters​

Here, the Host SDK will request the Host Server and obtain the game package download URL and game type based on the LAUNCH KEY. For the full list of parameters, refer to the API Reference. After success, game resources can be loaded.

async function setGameStartOptions() {
const options = {};
options[TJConstants.LAUNCH_KEY] = 'LAUNCH KEY';
options[TJConstants.USER_ID] = 'guest';

await gameHandle.setGameStartOptions(options);

// end of set game start options
}

4.3 Load Game Resources​

After success, the game window will be created, game resources will be downloaded and launched.

await gameHandle.start();

// end of game resources loading

4.4 Start the Game​

function showGame() {
if (!gameHandle) {
return;
}

gameHandle.play(); // start game
}

4.5 Close the game​

Add a game close listening callback to handle the game close logic

gameHandle.setOnTJCloseListener(() => {
// stop game
gameHandle.stop();
});

5 Multi-instance Game Management ​

The host provides MultiGameLauncher to manage multiple game instances. When the instances reach the upper limit, they will be automatically stopped based on time and then enabled as new instances.

5.1 Initialize the multi-instance upper limit​

const { MultiGameLauncher } = require('webglhost-runtime-pc');

MultiGameLauncher.configMaxGame(3); // default uninitialized number: 1

5.2 Create Host​

Creating a host for multiple instances requires binding through the gameId. If a host has already been created for an instance, the original host will be reused.

// createGameHandle: use gameId to get the corresponding instance
const gameHandle = await MultiGameLauncher.createGameHandle(hostHandle, gameId, {});

// end of RuntimeGameHandle initialization

5.3 Set game startup parameters​

Here, the Host SDK will request the Host Server and obtain the game package download URL and game type based on the LAUNCH KEY. For the full list of parameters, refer to the API Reference. After success, game resources can be loaded.

async function setGameStartOptions() {
const options = {};
options[TJConstants.LAUNCH_KEY] = 'LAUNCH KEY';
options[TJConstants.USER_ID] = 'guest';

await gameHandle.setGameStartOptions(options);

// end of set game start options
}

5.4 Load game resources​

After success, the game window will be created, and game resources will be downloaded.

await gameHandle.start();

5.5 Start the Game​

function showGame() {
if (!gameHandle) {
return;
}

gameHandle.play();
}

5.6 Pause Game​

Add a game close listening callback to handle the logic of pausing the game

MultiGameLauncher.pause(gameId);
MultiGameLauncher.pauseAll();

5.7 Resume Game​

Call the resume method when the game needs to be resumed

const { MiniGameLaunchOption } = require('webglhost-runtime-pc');

// configure hot-start params
const enterOption = new MiniGameLaunchOption({
scene: 1002,
shareTicket: '1002'
});

MultiGameLauncher.resume(gameId, enterOption);
// resume with no params
MultiGameLauncher.resume(gameId);

5.8 Stop the game​

When the game needs to be stopped or the page needs to be released, call MultiGameLauncher.stop(gameId) to release all associated information

MultiGameLauncher.stop(gameId);
MultiGameLauncher.stopAll();

5.9 Destroy Instance​

When an instance needs to be released, call MultiGameLauncher.destroy(gameId) to release the content associated with the instance. Destroying the instance will stop the game and release the instance.

MultiGameLauncher.destroy(gameId);
MultiGameLauncher.destroyAll();

6 Event Listening​

6.1 Basic Event​

// Game menu button clicked
gameHandle.setOnTJMenuListener(() => {
console.log('Menu clicked');
});

// Game close button clicked
gameHandle.setOnTJCloseListener(() => {
console.log('Close clicked');
gameHandle.stop();
});

// First frame rendered
gameHandle.setOnFirstFrameRenderedListener(() => {
console.log('First frame rendered');
});

// Game crashed
gameHandle.setOnHostFailureListener((error) => {
console.error('Game crashed:', error);
});

6.2 Custom Commands​

// Set custom command listener
gameHandle.setCustomCommandListener('customCommand', (request, handle) => {
console.log('Custom command received:', request);
handle.success({ result: 'success' });
});

// Run custom script in game
await gameHandle.runCustomScript(`
console.log('Hello from game!');
tj.customCommand({
command: 'customCommand',
data: { message: 'Hello from game!' }
});
`);

7 Audio Control​

// Mute all audio
gameHandle.muteAllAudio();

// Unmute all audio
gameHandle.unmuteAllAudio();

// Toggle audio mute
gameHandle.toggleAudioMute();

// Check if muted
const isMuted = gameHandle.isMuted();

8 Debugging Function​

// Open debug menu
gameHandle.showDebugMenu();

// Toggle debug mode
gameHandle.toggleDebugMode();

// Get debug mode status
const debugEnabled = gameHandle.getDebugModeStatus();

// Force garbage collection
gameHandle.invokeForceGC();

// Export logs
gameHandle.exportLogManagerLog();

9 API Reference​

9.1 TJConstants​

Game startup parameter constants:

const TJConstants = {
LAUNCH_KEY: 'launchKey', // Game launch key (required)
GAME_ID: 'gameId', // Game ID
USER_ID: 'userId', // User ID
ACCESS_TOKEN: 'accessToken', // Access token
ENABLE_VCONSOLE: 'enableVConsole', // Enable vConsole
ENABLE_INSPECTOR: 'enableInspector', // Enable inspector
ENABLE_MUTE_ALL_AUDIO: 'enableMuteAllAudio', // Mute all audio
ENABLE_TRANSPARENT_MODE: 'enableTransparentMode', // Transparent mode
INSPECTOR_WAIT_FOR_INSPECT: 'waitForInspect', // Wait for inspect
};

9.2 TJHostHandle​

9.2.1 Static Methods​

  • initialize(sdkKey, sdkSecret, completion) - Initialize SDK

  • setRuntimeEnv(env) - Set runtime environment

  • getVersionName() - Get version name

  • getVersionCode() - Get version code

  • getCommitId() - Get commit ID

9.2.2 Instance Methods​

  • createGameHandle(options) - Create game handle

  • initLog(logLevel, logger) - Initialize logging

  • setRecentlyGameListener(listener) - Set recently played game listener

  • getUserHistory(userId) - Get user history

9.3 RuntimeGameHandle​

9.3.1 Lifecycle Methods​

  • setGameStartOptions(options) - Set game start options

  • start() - Start game (download and initialize)

  • play() - Play game

  • pause() - Pause game

  • stop() - Stop game

  • restart() - Restart game

9.3.2 Event Listeners​

  • setOnTJMenuListener(callback) - Menu button clicked

  • setOnTJCloseListener(callback) - Close button clicked

  • setOnFirstFrameRenderedListener(callback) - First frame rendered

  • setOnHostFailureListener(callback) - Game crashed

  • setCustomCommandListener(command, callback) - Custom command

9.3.3 Audio Control​

  • muteAllAudio() - Mute all audio

  • unmuteAllAudio() - Unmute all audio

  • toggleAudioMute() - Toggle audio mute

  • isMuted() - Check if muted

9.3.4 Debug Methods​

  • showDebugMenu() - Show debug menu

  • toggleDebugMode() - Toggle debug mode

  • getDebugModeStatus() - Get debug mode status

  • invokeForceGC() - Force garbage collection

  • exportLogManagerLog() - Export logs

9.4 MultiGameLauncher​

9.4.1 Static Methods​

  • configMaxGame(max) - Configure max instances

  • createGameHandle(hostHandle, gameId, options, completion) - Create game handle

  • stopAll() - Stop all instances

  • stop(gameId) - Stop specified instance

  • pauseAll() - Pause all instances

  • pause(gameId) - Pause specified instance

  • resume(gameId, enterOption) - Resume specified instance

  • destroyAll() - Destroy all instances

  • destroy(gameId) - Destroy specified instance

9.4.2 Query Methods​

  • getGameHandle(gameId) - Get game handle

  • getAllTasks() - Get all tasks

  • getActiveGameCount() - Get active game count

  • isMaxReached() - Check if max reached

10 Error Handling​

const { HostRuntimeError } = require('webglhost-runtime-pc');

try {
const hostHandle = await TJHostHandle.initialize('invalid-key', 'invalid-secret');
} catch (error) {
if (error instanceof HostRuntimeError) {
switch (error.code) {
case 'SDK_INITIALIZATION_FAILED':
console.log('SDK initialization failed');
break;
case 'GAME_ID_NOT_SET':
console.log('Game ID not set');
break;
case 'LAUNCH_KEY_NOT_SET':
console.log('Launch key not set');
break;
default:
console.log('Unknown error:', error.message);
}
}
}

11 System Requirements​

  • Node.js: >= 20.0.0

  • Electron: >= 32.0.0

  • Operating Systems:

    • Windows 10+ (x64)

    • macOS 10.15+ (x64, arm64)

12 Precautions​

  1. Electron Environment: The SDK must run in an Electron environment

  2. Singleton Pattern: TJHostHandle is recommended to use the singleton pattern to avoid repeated initialization

  1. Resource Cleanup: When the game is closed, be sure to call the stop() or destroy() method to release resources

  2. Multi-instance Management: When using MultiGameLauncher, pay attention to configuring a reasonable maximum number of instances to avoid excessive resource consumption

  1. Error handling : All asynchronous operations should add appropriate error handling

  2. Logging: It is recommended to enable the logging function in the production environment to facilitate troubleshooting

13 Advanced Usage Scenarios​

For a deeper understanding of more advanced features, please refer to:

  • Advanced Usage Scenarios (See Advanced Usage) - Custom game window, transparent background, recently played list, etc.

  • Platform Capability Integration (See Platform Capability Integration) - Integrate Login SDK, Advertising SDK, and Payment SDK

14 More Information​