Preskoči na sadržaj

Klijentski SDK

Klijentski SDK radi direktno u igri. Preko njega čuvate podatke, proveravate autentifikaciju, čitate rang liste i izvršavate atomske operacije.

Instalacija

Terminal window
npm install @kruzic/game-sdk

Inicijalizacija

import { KruzicClient } from '@kruzic/game-sdk/client';
const sdk = new KruzicClient();
// Obavestite platformu da je igra spremna
sdk.ready();

Opcije

const sdk = new KruzicClient({
devMode: true, // Koristi localStorage umesto postMessage (za lokalni razvoj)
gameId: 'moja-igra' // ID igre za localStorage ključeve u dev mode-u
});

Kad igra nije pokrenuta unutar kružić platforme (iframe/WebView), SDK sam prelazi u dev mode i koristi localStorage. Razvijate i testirate lokalno bez deploy-a.

Autentifikacija

Provera prijave

const signedIn = await sdk.isSignedIn();
if (signedIn) {
console.log('Igrač je prijavljen');
} else {
console.log('Igrač igra kao gost');
}

ID korisnika

const userId = await sdk.getUserId();
// Vraća string ID ili null ako korisnik nije prijavljen

Detalji o korisniku

const user = await sdk.getUserDetails();
// {
// id: "abc123",
// name: "Marko",
// image: "https://..." ili null
// }

Čuvanje podataka

Sačuvaj vrednost

// Brojevi
await sdk.setData('highscore', 1500);
// Stringovi
await sdk.setData('playerName', 'Marko');
// Objekti (automatski se serijalizuju u JSON)
await sdk.setData('settings', {
sound: true,
difficulty: 'hard',
language: 'sr'
});
// Nizovi
await sdk.setData('inventory', ['sword', 'shield', 'potion']);

Učitaj vrednost

const score = await sdk.getData('highscore');
// 1500
const settings = await sdk.getData('settings');
// { sound: true, difficulty: 'hard', language: 'sr' }
const missing = await sdk.getData('nepostojeci_kljuc');
// null

Izlistaj sve ključeve

const keys = await sdk.listData();
// ['highscore', 'settings', 'inventory']

Obriši vrednost

await sdk.deleteData('old_save');

Atomski increment

Kad menjate brojčanu vrednost, increment je bolji izbor od getData + setData — operacija je atomska i nema race condition-a:

// Dodaj 1 (podrazumevano)
await sdk.increment('coins');
// Dodaj proizvoljnu vrednost
await sdk.increment('coins', 50);
// Oduzmi vrednost (negativan delta)
await sdk.increment('lives', -1);

Rang liste

Za brojčano polje sa uključenom rang listom (podešava se u kontrolnoj tabli), dostupni su sledeći pozivi:

Učitaj rang listu

const leaderboard = await sdk.getLeaderboard('highscore', {
limit: 10, // Broj unosa (opciono)
offset: 0 // Preskočite prvih N (opciono, za paginaciju)
});
// {
// entries: [
// { rank: 1, publicId: 42, username: "marko", name: "Marko", value: 5000, formattedValue: "5000" },
// { rank: 2, publicId: 15, username: "ana", name: "Ana", value: 4200, formattedValue: "4200" },
// ...
// ],
// total: 150,
// userRank: { rank: 23, value: 1500, formattedValue: "1500" },
// fieldInfo: { apiName: "highscore", displayName: "Najbolji rezultat", ... }
// }

Rang trenutnog igrača

const myRank = await sdk.getMyRank('highscore');
// { rank: 23, value: 1500, formattedValue: "1500" }
// ili null ako igrač nema rezultat

Data schema

Ako ste u kontrolnoj tabli definisali polja podataka, možete programski pročitati njihovu strukturu:

const schema = await sdk.getDataSchema();
// [
// { apiName: "highscore", type: "number", clientRead: true, clientWrite: true },
// { apiName: "settings", type: "json", clientRead: true, clientWrite: true },
// ...
// ]
// ili null ako schema nije definisana

Čišćenje

Kad igra završi ili se unmount-uje, pozovite destroy() da uklonite event listener-e:

sdk.destroy();

Primeri iz prakse

Highscore sistem

const sdk = new KruzicClient();
sdk.ready();
async function submitScore(score) {
// Ako koristite best score mode u kontrolnoj tabli,
// platforma automatski čuva samo bolji rezultat
await sdk.setData('highscore', score);
}
async function showLeaderboard() {
const lb = await sdk.getLeaderboard('highscore', { limit: 10 });
if (lb) {
lb.entries.forEach(entry => {
console.log(`#${entry.rank} ${entry.name}: ${entry.formattedValue}`);
});
}
}

Save/Load sistem

async function saveGame(state) {
await sdk.setData('save', {
level: state.level,
health: state.health,
inventory: state.inventory,
timestamp: Date.now()
});
}
async function loadGame() {
const save = await sdk.getData('save');
if (save) {
return save;
}
return { level: 1, health: 100, inventory: [] };
}

Podešavanja igrača

const DEFAULT_SETTINGS = {
sound: true,
music: true,
difficulty: 'normal'
};
async function loadSettings() {
const saved = await sdk.getData('settings');
return { ...DEFAULT_SETTINGS, ...saved };
}
async function saveSetting(key, value) {
const settings = await loadSettings();
settings[key] = value;
await sdk.setData('settings', settings);
}

API referenca

MetodaPovratna vrednostOpis
ready()voidJavlja platformi da je igra učitana
isSignedIn()Promise<boolean>Da li je igrač prijavljen
getUserId()Promise<string | null>ID prijavljenog korisnika
getUserDetails()Promise<UserDetails | null>Ime, ID i slika korisnika
getData(key)Promise<T | null>Učitava sačuvanu vrednost
setData(key, value)Promise<void>Čuva vrednost
deleteData(key)Promise<void>Briše vrednost
listData()Promise<string[]>Vraća sve ključeve
increment(key, delta?)Promise<void>Atomski increment (delta je 1 ako nije naveden)
getLeaderboard(field, opts?)Promise<LeaderboardResult | null>Rang lista za polje
getMyRank(field)Promise<UserRankResult | null>Rang trenutnog igrača
getDataSchema()Promise<SchemaField[] | null>Definisana polja podataka
destroy()voidUklanja event listener-e

Greške

Kad podatak ne postoji, SDK vraća null. Ako nešto pođe po zlu — mrežni problem, timeout — metoda baca error:

try {
await sdk.setData('key', 'value');
} catch (error) {
console.error('Greška pri čuvanju:', error.message);
}

Ugrađeni timeout je 10 sekundi. Ako platforma ne odgovori u tom roku, Promise se automatski reject-uje.