@oasiz/sdk 1.5.5 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -346
- package/dist/index.cjs +187 -1276
- package/dist/index.d.cts +97 -182
- package/dist/index.d.ts +97 -182
- package/dist/index.js +176 -1268
- package/package.json +4 -14
package/README.md
CHANGED
|
@@ -1,65 +1,47 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @oasiz/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Typed SDK for integrating games with the Oasiz platform. Handles score submission, haptic feedback, cross-session state persistence, multiplayer room codes, navigation hooks, and app lifecycle events for local development.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
| --- | --- | --- |
|
|
7
|
-
| **HTML5 / TypeScript** | [`@oasiz/sdk`](#html5--typescript-oasizsdk) (npm) | Canvas, Phaser, custom JS/TS, any browser game |
|
|
8
|
-
| **Unity WebGL** | [Unity runtime](#unity-webgl-sdk) in this repo (`packages/OasizSDK/`) | Unity projects targeting WebGL |
|
|
9
|
-
|
|
10
|
-
Both talk to the same host bridges (`window.submitScore`, `__oasizLeaveGame`, layout APIs, custom DOM events such as `oasiz:pause`, etc.). Unsupported hosts no-op safely; local dev usually logs warnings instead of crashing.
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## HTML5 / TypeScript (`@oasiz/sdk`)
|
|
15
|
-
|
|
16
|
-
Typed SDK for integrating browser games with the Oasiz platform: score, haptics, cross-session state, multiplayer hooks, layout (safe area, leaderboard visibility), navigation (back / leave), and lifecycle events.
|
|
17
|
-
|
|
18
|
-
### Install
|
|
5
|
+
## Install
|
|
19
6
|
|
|
20
7
|
```bash
|
|
21
|
-
npm install @oasiz/sdk
|
|
8
|
+
npm install @oasiz/sdk@^0.1.0
|
|
22
9
|
```
|
|
23
10
|
|
|
24
|
-
The published package includes ESM, CommonJS, and TypeScript declarations.
|
|
25
|
-
|
|
26
11
|
## Quick start
|
|
27
12
|
|
|
28
13
|
```ts
|
|
29
14
|
import { oasiz } from "@oasiz/sdk";
|
|
30
15
|
|
|
31
|
-
// 1.
|
|
16
|
+
// 1. Emit score normalization config once on init
|
|
17
|
+
oasiz.emitScoreConfig({
|
|
18
|
+
anchors: [
|
|
19
|
+
{ raw: 30, normalized: 100 },
|
|
20
|
+
{ raw: 60, normalized: 300 },
|
|
21
|
+
{ raw: 120, normalized: 600 },
|
|
22
|
+
{ raw: 300, normalized: 950 },
|
|
23
|
+
],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// 2. Load persisted state at the start of each session
|
|
32
27
|
const state = oasiz.loadGameState();
|
|
33
28
|
let level = typeof state.level === "number" ? state.level : 1;
|
|
34
29
|
|
|
35
|
-
//
|
|
30
|
+
// 3. Save state at checkpoints
|
|
36
31
|
oasiz.saveGameState({ level, coins: 42 });
|
|
37
32
|
|
|
38
|
-
//
|
|
33
|
+
// 4. Trigger haptics on key events
|
|
39
34
|
oasiz.triggerHaptic("medium");
|
|
40
35
|
|
|
41
|
-
// 4. Respect the host's top safe area (percent of viewport height → CSS vh)
|
|
42
|
-
document.documentElement.style.setProperty(
|
|
43
|
-
"--safe-top",
|
|
44
|
-
`${oasiz.safeAreaTop}vh`,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
36
|
// 5. Submit score when the game ends
|
|
48
37
|
oasiz.submitScore(score);
|
|
49
|
-
|
|
50
|
-
// 6. Optionally hide the leaderboard while a custom overlay is open
|
|
51
|
-
oasiz.setLeaderboardVisible(false);
|
|
52
|
-
|
|
53
|
-
// 7. Optionally surface console logs in-game while debugging
|
|
54
|
-
oasiz.enableLogOverlay({
|
|
55
|
-
enabled: new URLSearchParams(window.location.search).has("oasizLogs"),
|
|
56
|
-
collapsed: true,
|
|
57
|
-
});
|
|
58
38
|
```
|
|
59
39
|
|
|
60
|
-
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Score
|
|
61
43
|
|
|
62
|
-
|
|
44
|
+
### `oasiz.submitScore(score: number)`
|
|
63
45
|
|
|
64
46
|
Submit the player's final score at game over. Call this exactly once per session, when the game ends. The platform handles leaderboard persistence — do not track high scores locally.
|
|
65
47
|
|
|
@@ -72,9 +54,39 @@ private onGameOver(): void {
|
|
|
72
54
|
- `score` must be a non-negative integer. Floats are floored automatically.
|
|
73
55
|
- Do not call on intermediate scores or level completions, only on final game over.
|
|
74
56
|
|
|
75
|
-
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
### `oasiz.emitScoreConfig(config)`
|
|
60
|
+
|
|
61
|
+
Maps raw score values to the platform's normalized 0–1000 scale. Call once during initialization, not every frame.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
oasiz.emitScoreConfig({
|
|
65
|
+
anchors: [
|
|
66
|
+
{ raw: 10, normalized: 100 }, // beginner
|
|
67
|
+
{ raw: 30, normalized: 300 }, // good
|
|
68
|
+
{ raw: 75, normalized: 600 }, // great
|
|
69
|
+
{ raw: 200, normalized: 950 }, // godlike
|
|
70
|
+
],
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Anchor rules:**
|
|
75
|
+
- Exactly 4 anchors required.
|
|
76
|
+
- `raw` values must be strictly increasing.
|
|
77
|
+
- `normalized` values must end at exactly `950`.
|
|
78
|
+
- Choose thresholds based on realistic player skill bands.
|
|
76
79
|
|
|
77
|
-
|
|
80
|
+
**Practical guidance by game type:**
|
|
81
|
+
- Survival / time games → use seconds survived as `raw`
|
|
82
|
+
- Score accumulation games → use points as `raw`
|
|
83
|
+
- Puzzle games → use level reached or stars earned as `raw`
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Haptics
|
|
88
|
+
|
|
89
|
+
### `oasiz.triggerHaptic(type: HapticType)`
|
|
78
90
|
|
|
79
91
|
Trigger native haptic feedback. Always guard with the user's haptics setting.
|
|
80
92
|
|
|
@@ -83,7 +95,7 @@ type HapticType = "light" | "medium" | "heavy" | "success" | "error";
|
|
|
83
95
|
```
|
|
84
96
|
|
|
85
97
|
| Type | When to use |
|
|
86
|
-
|
|
98
|
+
|---|---|
|
|
87
99
|
| `"light"` | UI button taps, menu navigation, D-pad press |
|
|
88
100
|
| `"medium"` | Collecting items, standard collisions, scoring |
|
|
89
101
|
| `"heavy"` | Explosions, major impacts, screen shake |
|
|
@@ -114,45 +126,20 @@ private onGameOver(): void {
|
|
|
114
126
|
|
|
115
127
|
Haptics are throttled internally (50ms cooldown) to prevent spam.
|
|
116
128
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
#### `oasiz.enableLogOverlay(options?: LogOverlayOptions)`
|
|
120
|
-
|
|
121
|
-
Mount an opt-in in-game console viewer for local debugging, QA sessions, or creator support. It mirrors `console.log`, `console.info`, `console.warn`, `console.error`, and `console.debug` into a floating overlay inside the game iframe. The overlay can be collapsed, repositioned by dragging the top bar, and resized from the bottom-right corner while the action buttons remain clickable.
|
|
122
|
-
|
|
123
|
-
```ts
|
|
124
|
-
const logOverlay = oasiz.enableLogOverlay({
|
|
125
|
-
enabled: new URLSearchParams(window.location.search).has("oasizLogs"),
|
|
126
|
-
collapsed: true,
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
console.log("[Boot] Scene ready");
|
|
130
|
-
|
|
131
|
-
// Optional cleanup if your game tears down and remounts
|
|
132
|
-
logOverlay.destroy();
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Options:
|
|
136
|
-
|
|
137
|
-
- `enabled`: defaults to `true`. Pass your own flag or query-param check here.
|
|
138
|
-
- `collapsed`: start with only the toggle pill visible.
|
|
139
|
-
- `maxEntries`: cap retained log lines. Defaults to `200`.
|
|
140
|
-
- `title`: optional label shown at the top of the panel. Defaults to `SDK Logs`.
|
|
141
|
-
|
|
142
|
-
The returned handle supports `show()`, `hide()`, `clear()`, `isVisible()`, and `destroy()`.
|
|
129
|
+
---
|
|
143
130
|
|
|
144
|
-
|
|
131
|
+
## Game state persistence
|
|
145
132
|
|
|
146
133
|
Persist cross-session data such as unlocked levels, inventory, or lifetime stats. State is stored per-user per-game in the Oasiz backend — available across devices and app reinstalls.
|
|
147
134
|
|
|
148
|
-
|
|
135
|
+
### `oasiz.loadGameState(): Record<string, unknown>`
|
|
149
136
|
|
|
150
137
|
Returns the player's saved state synchronously. Returns `{}` if no state has been saved yet. Call once at the start of the game.
|
|
151
138
|
|
|
152
139
|
```ts
|
|
153
140
|
private initFromSavedState(): void {
|
|
154
141
|
const state = oasiz.loadGameState();
|
|
155
|
-
this.level
|
|
142
|
+
this.level = typeof state.level === "number" ? state.level : 1;
|
|
156
143
|
this.lifetimeHits = typeof state.lifetimeHits === "number" ? state.lifetimeHits : 0;
|
|
157
144
|
this.unlockedSkins = Array.isArray(state.unlockedSkins) ? state.unlockedSkins : [];
|
|
158
145
|
}
|
|
@@ -160,7 +147,7 @@ private initFromSavedState(): void {
|
|
|
160
147
|
|
|
161
148
|
Always validate the shape of loaded data — it may be `{}` on first play.
|
|
162
149
|
|
|
163
|
-
|
|
150
|
+
### `oasiz.saveGameState(state: Record<string, unknown>)`
|
|
164
151
|
|
|
165
152
|
Queues a debounced save. Saves are batched automatically — call freely at checkpoints without worrying about request spam.
|
|
166
153
|
|
|
@@ -177,12 +164,11 @@ private onLevelComplete(): void {
|
|
|
177
164
|
```
|
|
178
165
|
|
|
179
166
|
**Rules:**
|
|
180
|
-
|
|
181
167
|
- State must be a plain JSON object (not an array or primitive).
|
|
182
168
|
- Do not use `localStorage` for cross-session progress — use `saveGameState` so data syncs across platforms.
|
|
183
169
|
- Do not store scores here — scores are submitted via `submitScore`.
|
|
184
170
|
|
|
185
|
-
|
|
171
|
+
### `oasiz.flushGameState()`
|
|
186
172
|
|
|
187
173
|
Forces an immediate write, bypassing the debounce. Use at important checkpoints like game over or before the page unloads.
|
|
188
174
|
|
|
@@ -194,63 +180,19 @@ private onGameOver(): void {
|
|
|
194
180
|
}
|
|
195
181
|
```
|
|
196
182
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
Use the runtime safe-area value instead of hardcoded top offsets. The SDK returns the top inset as **a percentage of the active viewport height (0–100)**. If the host exposes CSS pixels via `window.getSafeAreaTop()` or `window.__OASIZ_SAFE_AREA_TOP__`, the SDK converts using `window.visualViewport.height` when available, then `window.innerHeight`, then document height. The host may instead set **`window.getSafeAreaTopPercent()`** or **`window.__OASIZ_SAFE_AREA_TOP_PERCENT__`** (0–100) and that value is used directly. When no host bridge is available, the SDK falls back to CSS `env(safe-area-inset-top)` / `constant(safe-area-inset-top)`.
|
|
200
|
-
|
|
201
|
-
#### `oasiz.getSafeAreaTop(): number`
|
|
202
|
-
|
|
203
|
-
Returns the top inset as a percentage of viewport height (0–100). To get pixels in JavaScript, multiply by `window.visualViewport?.height || window.innerHeight`. In CSS, the same value matches **`vh`** units (for example `12.5vh` for 12.5% of the viewport height). Unsupported hosts return `0`.
|
|
204
|
-
|
|
205
|
-
```ts
|
|
206
|
-
const safeTopPct = oasiz.getSafeAreaTop();
|
|
207
|
-
document.documentElement.style.setProperty("--safe-top", `${safeTopPct}vh`);
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
#### `oasiz.safeAreaTop`
|
|
211
|
-
|
|
212
|
-
Getter alias for `getSafeAreaTop()`.
|
|
213
|
-
|
|
214
|
-
Recommended CSS pattern:
|
|
215
|
-
|
|
216
|
-
```css
|
|
217
|
-
:root {
|
|
218
|
-
--safe-top: 0px;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
#top-bar {
|
|
222
|
-
padding-top: var(--safe-top);
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
#### `oasiz.setLeaderboardVisible(visible: boolean): void`
|
|
227
|
-
|
|
228
|
-
Show or hide the host leaderboard UI from inside the game. This only affects the leaderboard; back and social controls remain visible. Calls `window.__oasizSetLeaderboardVisible` when present.
|
|
229
|
-
|
|
230
|
-
```ts
|
|
231
|
-
function openCustomOverlay(): void {
|
|
232
|
-
oasiz.setLeaderboardVisible(false);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function closeCustomOverlay(): void {
|
|
236
|
-
oasiz.setLeaderboardVisible(true);
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
Unsupported hosts safely no-op.
|
|
183
|
+
---
|
|
241
184
|
|
|
242
|
-
|
|
185
|
+
## Lifecycle
|
|
243
186
|
|
|
244
187
|
The platform dispatches lifecycle events when the app goes to the background or returns to the foreground. Subscribe to pause game loops and audio accordingly.
|
|
245
188
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
#### `oasiz.onResume(callback: () => void): Unsubscribe`
|
|
189
|
+
### `oasiz.onPause(callback: () => void): Unsubscribe`
|
|
190
|
+
### `oasiz.onResume(callback: () => void): Unsubscribe`
|
|
249
191
|
|
|
250
192
|
Both return an unsubscribe function.
|
|
251
193
|
|
|
252
194
|
```ts
|
|
253
|
-
const offPause
|
|
195
|
+
const offPause = oasiz.onPause(() => {
|
|
254
196
|
this.gameLoop.stop();
|
|
255
197
|
this.bgMusic.pause();
|
|
256
198
|
});
|
|
@@ -265,17 +207,19 @@ offPause();
|
|
|
265
207
|
offResume();
|
|
266
208
|
```
|
|
267
209
|
|
|
268
|
-
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Navigation
|
|
269
213
|
|
|
270
214
|
Use navigation hooks when your game needs to control back behavior (Android back / web Escape) or participate in host-driven close events.
|
|
271
215
|
|
|
272
|
-
|
|
216
|
+
### `oasiz.onBackButton(callback: () => void): Unsubscribe`
|
|
273
217
|
|
|
274
218
|
Registers a callback for platform back actions. While at least one back listener is subscribed, back actions are routed to your game instead of immediately closing it.
|
|
275
219
|
|
|
276
220
|
Use this for pause menus, in-game overlays, or custom back-stack behavior.
|
|
277
221
|
|
|
278
|
-
|
|
222
|
+
If your callback throws, Oasiz falls back to closing the game and returning the player to Oasiz home before rethrowing the error for debugging/reporting.
|
|
279
223
|
|
|
280
224
|
```ts
|
|
281
225
|
const offBack = oasiz.onBackButton(() => {
|
|
@@ -290,7 +234,7 @@ const offBack = oasiz.onBackButton(() => {
|
|
|
290
234
|
offBack();
|
|
291
235
|
```
|
|
292
236
|
|
|
293
|
-
|
|
237
|
+
### `oasiz.leaveGame(): void`
|
|
294
238
|
|
|
295
239
|
Programmatically request the host to close the current game (for example, from a Quit button inside your game UI).
|
|
296
240
|
|
|
@@ -325,13 +269,13 @@ const offLeave = oasiz.onLeaveGame(() => {
|
|
|
325
269
|
offLeave();
|
|
326
270
|
```
|
|
327
271
|
|
|
328
|
-
|
|
272
|
+
---
|
|
329
273
|
|
|
330
|
-
|
|
274
|
+
## Multiplayer
|
|
331
275
|
|
|
332
|
-
|
|
276
|
+
### `oasiz.shareRoomCode(code: string | null)`
|
|
333
277
|
|
|
334
|
-
|
|
278
|
+
Notify the platform of the active multiplayer room so friends can join via the invite system. Pass `null` when leaving a room.
|
|
335
279
|
|
|
336
280
|
```ts
|
|
337
281
|
import { insertCoin, getRoomCode } from "playroomkit";
|
|
@@ -344,26 +288,7 @@ oasiz.shareRoomCode(getRoomCode());
|
|
|
344
288
|
oasiz.shareRoomCode(null);
|
|
345
289
|
```
|
|
346
290
|
|
|
347
|
-
|
|
348
|
-
// Game-owned invite UI: hide the platform pill, keep room tracking
|
|
349
|
-
oasiz.shareRoomCode(getRoomCode(), { inviteOverride: true });
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
#### `oasiz.openInviteModal(): void`
|
|
353
|
-
|
|
354
|
-
Opens the platform invite-friends UI when the bridge is available. Typically used together with `shareRoomCode` (for example, your own invite button calls this).
|
|
355
|
-
|
|
356
|
-
```ts
|
|
357
|
-
import { openInviteModal, shareRoomCode } from "@oasiz/sdk";
|
|
358
|
-
|
|
359
|
-
shareRoomCode("ABCD", { inviteOverride: true });
|
|
360
|
-
|
|
361
|
-
inviteButton.addEventListener("click", () => {
|
|
362
|
-
openInviteModal();
|
|
363
|
-
});
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
#### Read-only injected values
|
|
291
|
+
### Read-only injected values
|
|
367
292
|
|
|
368
293
|
These are populated by the platform before the game loads. Always check for `undefined` before using.
|
|
369
294
|
|
|
@@ -377,27 +302,25 @@ if (oasiz.roomCode) {
|
|
|
377
302
|
}
|
|
378
303
|
|
|
379
304
|
// Player identity for multiplayer games
|
|
380
|
-
const name
|
|
305
|
+
const name = oasiz.playerName;
|
|
381
306
|
const avatar = oasiz.playerAvatar;
|
|
382
307
|
```
|
|
383
308
|
|
|
384
|
-
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Named exports
|
|
385
312
|
|
|
386
313
|
All methods are also available as named exports if you prefer not to use the `oasiz` namespace object:
|
|
387
314
|
|
|
388
315
|
```ts
|
|
389
316
|
import {
|
|
390
317
|
submitScore,
|
|
391
|
-
|
|
318
|
+
emitScoreConfig,
|
|
392
319
|
triggerHaptic,
|
|
393
320
|
loadGameState,
|
|
394
321
|
saveGameState,
|
|
395
322
|
flushGameState,
|
|
396
323
|
shareRoomCode,
|
|
397
|
-
openInviteModal,
|
|
398
|
-
enableLogOverlay,
|
|
399
|
-
getSafeAreaTop,
|
|
400
|
-
setLeaderboardVisible,
|
|
401
324
|
onPause,
|
|
402
325
|
onResume,
|
|
403
326
|
onBackButton,
|
|
@@ -410,199 +333,18 @@ import {
|
|
|
410
333
|
} from "@oasiz/sdk";
|
|
411
334
|
```
|
|
412
335
|
|
|
413
|
-
### TypeScript types
|
|
414
|
-
|
|
415
|
-
```ts
|
|
416
|
-
import type {
|
|
417
|
-
GameState,
|
|
418
|
-
HapticType,
|
|
419
|
-
LogOverlayEntry,
|
|
420
|
-
LogOverlayHandle,
|
|
421
|
-
LogOverlayLevel,
|
|
422
|
-
LogOverlayOptions,
|
|
423
|
-
ShareRequest,
|
|
424
|
-
ShareRoomCodeOptions,
|
|
425
|
-
Unsubscribe,
|
|
426
|
-
} from "@oasiz/sdk";
|
|
427
|
-
```
|
|
428
|
-
|
|
429
336
|
---
|
|
430
337
|
|
|
431
|
-
##
|
|
432
|
-
|
|
433
|
-
C# API and **WebGL-only** `OasizBridge.jslib` live in this repository at **`packages/OasizSDK/`**. Copy the **`OasizSDK`** folder into your Unity project under **`Assets/`** (for example `Assets/OasizSDK`).
|
|
434
|
-
|
|
435
|
-
### Setup
|
|
436
|
-
|
|
437
|
-
1. Copy `packages/OasizSDK` from this repo into `Assets/OasizSDK`.
|
|
438
|
-
2. Ensure the **WebGL** platform is selected for release builds; the `.jslib` under `Runtime/Plugins/WebGL/` is included automatically for WebGL.
|
|
439
|
-
3. Add an **`OasizSDK`** component to a persistent GameObject early (for example a bootstrap scene), **or** rely on `OasizSDK.Instance` which creates a `DontDestroyOnLoad` object. The component registers listeners for `oasiz:pause`, `oasiz:resume`, `oasiz:back`, and `oasiz:leave` via `SendMessage`.
|
|
440
|
-
|
|
441
|
-
### Quick start
|
|
442
|
-
|
|
443
|
-
```csharp
|
|
444
|
-
using Oasiz;
|
|
445
|
-
using UnityEngine;
|
|
446
|
-
|
|
447
|
-
public class GameManager : MonoBehaviour
|
|
448
|
-
{
|
|
449
|
-
void Start()
|
|
450
|
-
{
|
|
451
|
-
// Ensure the singleton is initialized early
|
|
452
|
-
_ = OasizSDK.Instance;
|
|
453
|
-
|
|
454
|
-
// Subscribe to lifecycle events
|
|
455
|
-
OasizSDK.OnPause += OnPause;
|
|
456
|
-
OasizSDK.OnResume += OnResume;
|
|
457
|
-
|
|
458
|
-
// Offset UI for the host's top safe area (0–100 percent of Screen.height)
|
|
459
|
-
float safeTopPct = OasizSDK.SafeAreaTop;
|
|
460
|
-
float safeTopPx = safeTopPct / 100f * Screen.height;
|
|
461
|
-
Debug.Log($"Safe area top: {safeTopPx}px ({safeTopPct}% of height)");
|
|
462
|
-
|
|
463
|
-
// Emit score normalization anchors
|
|
464
|
-
OasizSDK.EmitScoreConfig(new ScoreConfig(
|
|
465
|
-
new ScoreAnchor(10, 100),
|
|
466
|
-
new ScoreAnchor(30, 300),
|
|
467
|
-
new ScoreAnchor(75, 600),
|
|
468
|
-
new ScoreAnchor(200, 950)
|
|
469
|
-
));
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
void OnGameOver(int finalScore)
|
|
473
|
-
{
|
|
474
|
-
OasizSDK.SubmitScore(finalScore);
|
|
475
|
-
OasizSDK.FlushGameState();
|
|
476
|
-
OasizSDK.SetLeaderboardVisible(true);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
void OnGameplayStart()
|
|
480
|
-
{
|
|
481
|
-
OasizSDK.SetLeaderboardVisible(false);
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
void OnPause() => Time.timeScale = 0f;
|
|
485
|
-
void OnResume() => Time.timeScale = 1f;
|
|
486
|
-
|
|
487
|
-
void OnDestroy()
|
|
488
|
-
{
|
|
489
|
-
OasizSDK.OnPause -= OnPause;
|
|
490
|
-
OasizSDK.OnResume -= OnResume;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
### API parity (TypeScript → C#)
|
|
496
|
-
|
|
497
|
-
| HTML5 (`@oasiz/sdk`) | Unity (`Oasiz` namespace) |
|
|
498
|
-
| --- | --- |
|
|
499
|
-
| `oasiz.submitScore(n)` | `OasizSDK.SubmitScore(int)` |
|
|
500
|
-
| `oasiz.triggerHaptic(type)` | `OasizSDK.TriggerHaptic(HapticType)` |
|
|
501
|
-
| `oasiz.loadGameState()` | `OasizSDK.LoadGameState()` → `Dictionary<string, object>` |
|
|
502
|
-
| `oasiz.saveGameState(obj)` | `OasizSDK.SaveGameState(Dictionary<string, object>)` |
|
|
503
|
-
| `oasiz.flushGameState()` | `OasizSDK.FlushGameState()` |
|
|
504
|
-
| `oasiz.getSafeAreaTop()` / `safeAreaTop` | `OasizSDK.GetSafeAreaTop()` / `OasizSDK.SafeAreaTop` (`float`, 0–100, % of viewport height) |
|
|
505
|
-
| `oasiz.setLeaderboardVisible(v)` | `OasizSDK.SetLeaderboardVisible(bool)` |
|
|
506
|
-
| `oasiz.onPause` / `onResume` | `OasizSDK.OnPause` / `OnResume` static events |
|
|
507
|
-
| `oasiz.onBackButton` | `OasizSDK.OnBackButton` or `SubscribeBackButton(Action)` (reference-counts `__oasizSetBackOverride`) |
|
|
508
|
-
| `oasiz.onLeaveGame` | `OasizSDK.OnLeaveGame` |
|
|
509
|
-
| `oasiz.leaveGame()` | `OasizSDK.LeaveGame()` |
|
|
510
|
-
| `oasiz.share(request)` | `OasizSDK.Share(ShareRequest)` |
|
|
511
|
-
| `oasiz.shareRoomCode` | `OasizSDK.ShareRoomCode(string, ShareRoomCodeOptions)` |
|
|
512
|
-
| `oasiz.openInviteModal()` | `OasizSDK.OpenInviteModal()` |
|
|
513
|
-
| `oasiz.gameId` / `roomCode` / ... | `OasizSDK.GameId` / `RoomCode` / `PlayerName` / `PlayerAvatar` |
|
|
514
|
-
| -- | `OasizSDK.EmitScoreConfig(ScoreConfig)` → `window.emitScoreConfig` (Unity-only helper for normalized score UI) |
|
|
515
|
-
| `oasiz.enableLogOverlay` | `OasizSDK.EnableLogOverlay(LogOverlayOptions)` (see note below) |
|
|
516
|
-
| -- | `OasizSDK.AppendLogOverlay(level, message, stackTrace)` (see note below) |
|
|
517
|
-
|
|
518
|
-
### Share (Unity)
|
|
519
|
-
|
|
520
|
-
HTML5 **`oasiz.share`** returns a **Promise** you can `await`. Unity **`OasizSDK.Share(ShareRequest)`** returns **`void`**: C# validation throws **`ArgumentException`** with the same rules as TypeScript (at least one of text, score, or image; non-negative integer score; `http(s)` or `data:image/...;base64,...` image). The call forwards JSON to **`window.__oasizShareRequest`**. If the host promise rejects, the **WebGL `.jslib` logs the error** to the browser console.
|
|
521
|
-
|
|
522
|
-
```csharp
|
|
523
|
-
OasizSDK.Share(new ShareRequest
|
|
524
|
-
{
|
|
525
|
-
Text = "Beat this run!",
|
|
526
|
-
Score = 1200,
|
|
527
|
-
Image = "https://example.com/card.png",
|
|
528
|
-
});
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
### Types
|
|
532
|
-
|
|
533
|
-
```csharp
|
|
534
|
-
// Haptic feedback intensity
|
|
535
|
-
public enum HapticType { Light, Medium, Heavy, Success, Error }
|
|
536
|
-
|
|
537
|
-
// Score normalization (exactly 4 anchors required)
|
|
538
|
-
public struct ScoreAnchor { public int raw; public int normalized; }
|
|
539
|
-
public struct ScoreConfig { public ScoreAnchor[] anchors; }
|
|
540
|
-
|
|
541
|
-
// Host share sheet (text / score / image URL or data URL)
|
|
542
|
-
public class ShareRequest
|
|
543
|
-
{
|
|
544
|
-
public string Text { get; set; }
|
|
545
|
-
public int? Score { get; set; }
|
|
546
|
-
public string Image { get; set; }
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
// Multiplayer invite options
|
|
550
|
-
public class ShareRoomCodeOptions { public bool InviteOverride { get; set; } }
|
|
551
|
-
|
|
552
|
-
// Log overlay configuration
|
|
553
|
-
public class LogOverlayOptions
|
|
554
|
-
{
|
|
555
|
-
public bool Enabled { get; set; } = true;
|
|
556
|
-
public bool Collapsed { get; set; } = false;
|
|
557
|
-
public int MaxEntries { get; set; } = 200;
|
|
558
|
-
public string Title { get; set; } = "SDK Logs";
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Log overlay lifecycle handle
|
|
562
|
-
public class LogOverlayHandle
|
|
563
|
-
{
|
|
564
|
-
public void Clear();
|
|
565
|
-
public void Hide();
|
|
566
|
-
public void Show();
|
|
567
|
-
public bool IsVisible();
|
|
568
|
-
public void Destroy();
|
|
569
|
-
}
|
|
570
|
-
```
|
|
338
|
+
## TypeScript types
|
|
571
339
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
Matching the HTML5 SDK: if any **`OnBackButton`** handler throws, **`OasizSDK.LeaveGame()`** is invoked and the **original exception is rethrown** (`throw;` preserves the stack trace). Use **`SubscribeBackButton`** when you want an unsubscribe delegate; you can also use `OnBackButton +=` / `-=` directly.
|
|
575
|
-
|
|
576
|
-
```csharp
|
|
577
|
-
// Subscribe with automatic unsubscribe support
|
|
578
|
-
var offBack = OasizSDK.SubscribeBackButton(() =>
|
|
579
|
-
{
|
|
580
|
-
if (isPaused)
|
|
581
|
-
Resume();
|
|
582
|
-
else
|
|
583
|
-
Pause();
|
|
584
|
-
});
|
|
585
|
-
|
|
586
|
-
// Unsubscribe when no longer needed
|
|
587
|
-
offBack();
|
|
340
|
+
```ts
|
|
341
|
+
import type { HapticType, ScoreConfig, ScoreAnchor, GameState } from "@oasiz/sdk";
|
|
588
342
|
```
|
|
589
343
|
|
|
590
|
-
### Editor vs WebGL builds
|
|
591
|
-
|
|
592
|
-
In the **Unity Editor**, bridge calls are mostly **logged** and return safe defaults (for example safe area `0`, `null` platform IDs). Real host integration applies to **WebGL player** builds running inside Oasiz.
|
|
593
|
-
|
|
594
|
-
### Log overlay (Unity)
|
|
595
|
-
|
|
596
|
-
The C# API for the log overlay exists for API compatibility, but the **default `OasizBridge.jslib` in this repo does not inject DOM UI** — `EnableLogOverlay` / `AppendLogOverlay` are no-ops at the JavaScript layer. Use Unity's console and device logs for debugging unless you replace or extend the `.jslib` on your side.
|
|
597
|
-
|
|
598
|
-
`AppendLogOverlay(level, message, stackTrace)` lets you pipe `Debug.Log` output into the overlay manually, since many embedded WebViews do not route Unity player logs through `console.log`. Valid levels: `"debug"`, `"log"`, `"info"`, `"warn"`, `"error"`.
|
|
599
|
-
|
|
600
344
|
---
|
|
601
345
|
|
|
602
346
|
## Local development
|
|
603
347
|
|
|
604
|
-
### HTML5 / TypeScript
|
|
605
|
-
|
|
606
348
|
All methods safely no-op when the platform bridges are not injected. In development mode a console warning is logged so you know the call was made:
|
|
607
349
|
|
|
608
350
|
```
|
|
@@ -610,7 +352,3 @@ All methods safely no-op when the platform bridges are not injected. In developm
|
|
|
610
352
|
```
|
|
611
353
|
|
|
612
354
|
No crashes, no special setup required for local dev.
|
|
613
|
-
|
|
614
|
-
### Unity WebGL
|
|
615
|
-
|
|
616
|
-
The `.jslib` logs warnings when `window.*` bridges are missing (for example `submitScore`, `__oasizLeaveGame`). The Editor path avoids calling native plugins and prints `Debug.Log` for most operations instead.
|