JavaScript SDK
Integrating JavaScript with StarWatch is a two-part process. First, your StarWatch instance needs to be created within the StarWatch Manager. Then the StarWatch SDK needs to be installed and integrated into your project.
Collect credentials
- Go to the manager site.
- Select your team.
- Select Manage on the instance.
- Click to copy your app key, secret key (needed for server-side integration) and API URL.
Have these items ready to use for the installation process.
Install
Install the SDK from npm:
npm install starwatch-sdkThe package resolves to the correct build automatically based on your environment (browser or Node.js), so the same import works from either side:
import { initialize } from 'starwatch-sdk';Initialize
Browser (client-side)
Client-side initialization uses Open Identification, so no secret key is required. Automatic fields such as FPS, platform, and device language are collected for you.
import { initialize } from 'starwatch-sdk';
initialize({
authType: 'open',
appKey: '[YOUR_APP_KEY]',
serverURL: '[YOUR_API_URL]',
getUsers: () => [
{
// `currentUser` is a placeholder — supply your own locally tracked user object
userID: currentUser.id,
level: currentUser.levelName,
position: currentUser.position,
countryCode: currentUser.countryCode,
},
],
});getUsers is called on every reporting tick. Return the latest position, level, and ID for each locally tracked user.
Node (server-side)
Server-side initialization requires both the app key and secret key, and reports on behalf of every connected player.
import { initialize } from 'starwatch-sdk';
initialize({
appKey: '[YOUR_APP_KEY]',
secretKey: '[YOUR_SECRET_KEY]',
serverURL: '[YOUR_API_URL]',
getUsers: () =>
// `connectedPlayers` is a placeholder — supply your own list of connected players
connectedPlayers.map((player) => ({
userID: player.id,
level: player.levelName,
position: player.position,
deviceLang: player.deviceLang,
fps: player.fps,
platform: player.platform,
countryCode: player.countryCode,
})),
});On Node, getUsers must supply every automatic field (deviceLang, fps, platform) yourself, since there’s no browser to infer them from.
Restricted Identification (player-issued tokens)
For multiplayer games where user IDs must be authorized by your game server, generate a per-player token on the server and hand it to the client instead of initializing the client with an app key.
Server, mint a token for the player:
import { authenticatePlayer } from 'starwatch-sdk';
const authorization = await authenticatePlayer(player.id);
// Send `authorization` to the client over your own connectionClient, initialize with that token:
import { initialize } from 'starwatch-sdk';
initialize({
authType: 'federated',
authorization, // received from your server
serverURL: '[YOUR_API_URL]',
getUsers: () => [
{
userID: currentUser.id,
level: currentUser.levelName,
position: currentUser.position,
countryCode: currentUser.countryCode,
},
],
});authenticatePlayer requires the server to already be authenticated, so the server’s own initialize call must complete first.
Refresh the federated token before it expires and hand the client the new one:
import { onAuthorizationExpiringSoon, updateAuthorization } from 'starwatch-sdk';
onAuthorizationExpiringSoon(async () => {
const authorization = await requestFreshTokenFromServer();
updateAuthorization(authorization);
});Submit game state
This content is optional for seeing users move around the map, but required for event-based features.
Submit events
import { submitEvent } from 'starwatch-sdk';
submitEvent({
event: 'player_jumped',
level: currentUser.levelName,
userID: currentUser.id,
});Attach extra metadata to an event with extraDetails:
submitEvent({
event: 'damage_taken',
level: currentUser.levelName,
userID: currentUser.id,
extraDetails: { amount: 25 },
});Submit chat events
StarWatch provides specialized tracking for chat messages:
import { submitChatEvent } from 'starwatch-sdk';
submitChatEvent({
message: 'Hello world!',
level: currentUser.levelName,
userID: currentUser.id,
});Chat events can also carry moderation flags and metadata:
submitChatEvent({
message: 'This might be inappropriate',
level: currentUser.levelName,
userID: currentUser.id,
flagged: true,
annotation: 'Flagged by moderation system',
tag: 'moderated-message',
});All parameters besides message, level, and userID are optional. flagged defaults to false.
Set gauges
import { setGauge, removeGauge } from 'starwatch-sdk';
// Update gauges only when the value changes
setGauge({
gauge: 'health',
userID: currentUser.id,
value: currentUser.health,
});
// Remove a gauge once it no longer applies
removeGauge({
gauge: 'health',
userID: currentUser.id,
});First login tracking
Report and look up when a user first played, independent of ongoing event/gauge telemetry.
Report a first login
import { reportFirstLogin } from 'starwatch-sdk';
reportFirstLogin({
userID: currentUser.id,
// Optional: defaults to now if omitted
firstLoginTime: Date.now(),
});Each user’s first login is only ever reported once; later calls for the same userID are ignored.
Query a first login
Available on Node only:
import { queryFirstLogin } from 'starwatch-sdk';
const result = await queryFirstLogin(player.id);
if (result?.data) {
console.log('First played at', new Date(result.data.time));
}Handle SDK lifecycle events
Register callbacks to observe what the SDK is doing internally.
import {
onAuthorizationExpiringSoon,
onAuthStateChanged,
onErrorLog,
onFlush,
} from 'starwatch-sdk';
// Fires whenever the SDK transitions between authenticated and unauthenticated
onAuthStateChanged((isAuthed) => {
console.log('Starwatch authenticated:', isAuthed);
});
// Fires on any internal SDK error (failed requests, bad responses, etc.)
onErrorLog((message) => {
console.error('Starwatch error:', message);
});
// Fires right before each periodic flush (every ~2 seconds)
onFlush(() => {
// Good place to sync any state your `getUsers` callback depends on, or to
// batch setGauge/removeGauge calls right before the values are sent instead
// of on every change
});
// Browser-only: fires ahead of a federated token expiring (see Restricted
// Identification above)
onAuthorizationExpiringSoon(() => {
// Request a fresh token and call updateAuthorization with it
});