2026-09-17 15:28:08 +03:00
|
|
|
# Player — `client.player`
|
2026-08-29 11:46:20 +03:00
|
|
|
|
|
|
|
|
`PlayerDomain` (source: `src/domains/PlayerDomain.ts`) — the observable player
|
2026-09-21 23:39:02 +03:00
|
|
|
profile: player, linked identities, currency balances and inventory stacks.
|
|
|
|
|
Synced under revision key `profile`.
|
2026-08-29 11:46:20 +03:00
|
|
|
|
2026-09-21 23:39:02 +03:00
|
|
|
There is no separate ledger service in this SDK. Balances and items are read
|
|
|
|
|
from the profile and are written server-side (admin adjust, module functions).
|
2026-08-29 11:46:20 +03:00
|
|
|
|
|
|
|
|
## Surface
|
|
|
|
|
|
|
|
|
|
`client.player` is a `SyncedState<PlayerProfile>`:
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-09-17 15:28:08 +03:00
|
|
|
client.player.value // PlayerProfile | undefined
|
2026-08-29 11:46:20 +03:00
|
|
|
client.player.status // 'idle' | 'loading' | 'ready' | 'error'
|
|
|
|
|
client.player.onChange((snapshot) => { /* fires immediately */ });
|
|
|
|
|
await client.player.load();
|
|
|
|
|
await client.player.reload(); // force refetch
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Types
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
interface PlayerProfile {
|
2026-09-24 14:13:35 +03:00
|
|
|
balances?: CurrencyBalance[];
|
2026-09-08 16:05:00 +03:00
|
|
|
identities?: PlayerProfileIdentity[];
|
2026-09-21 23:39:02 +03:00
|
|
|
items?: InventoryStack[];
|
2026-08-29 11:46:20 +03:00
|
|
|
player?: Player;
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-08 16:05:00 +03:00
|
|
|
interface PlayerProfileIdentity {
|
|
|
|
|
createdAt: string;
|
|
|
|
|
provider: string; // 'device' | 'google' | 'apple' | 'custom' | 'custom:<name>'
|
|
|
|
|
subject: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-29 11:46:20 +03:00
|
|
|
interface Player {
|
|
|
|
|
createdAt?: string;
|
|
|
|
|
id?: string;
|
|
|
|
|
language?: string;
|
|
|
|
|
nickname?: string;
|
|
|
|
|
projectId?: string;
|
|
|
|
|
region?: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-24 14:13:35 +03:00
|
|
|
interface CurrencyBalance {
|
2026-08-29 11:46:20 +03:00
|
|
|
balance?: number;
|
2026-09-21 23:39:02 +03:00
|
|
|
currency?: string; // currency slug configured in the dashboard
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface InventoryStack {
|
|
|
|
|
item?: string; // item slug
|
|
|
|
|
quantity?: number;
|
2026-08-29 11:46:20 +03:00
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Behavior notes
|
|
|
|
|
|
2026-09-21 23:39:02 +03:00
|
|
|
- `balances` carries one entry per currency in the latest release, zero-filled
|
|
|
|
|
for a player who never received it; `items` carries one entry per non-empty
|
|
|
|
|
inventory stack. Both bump the `profile` revision when they change.
|
2026-09-17 12:08:03 +03:00
|
|
|
- Warmed automatically at login (with catalog).
|
|
|
|
|
- Kept fresh by the revision poll; call `reload()` after a module function
|
2026-09-21 23:39:02 +03:00
|
|
|
that changes balances or items.
|
2026-08-29 11:46:20 +03:00
|
|
|
- All fields are optional on the wire (`?`); code defensively.
|
|
|
|
|
- React: `useSyncExternalStore` maps directly onto `onChange` (see the SDK
|
|
|
|
|
README "React recipe").
|