@hyve-sdk/js 2.14.0 → 2.14.1-canary.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 +13 -0
- package/dist/index.d.mts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +25 -3
- package/dist/index.mjs +25 -3
- package/dist/react.d.mts +2 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +25 -3
- package/dist/react.mjs +25 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -244,6 +244,19 @@ await hyve.gameplayStop();
|
|
|
244
244
|
await hyve.happytime();
|
|
245
245
|
```
|
|
246
246
|
|
|
247
|
+
Gameplay start/stop tracking is handled automatically where the SDK has the
|
|
248
|
+
context to do so:
|
|
249
|
+
|
|
250
|
+
- `gameplayStart()` and `gameplayEnd()` lifecycle telemetry calls forward to
|
|
251
|
+
the CrazyGames SDK, so games emitting the required Hyve lifecycle events get
|
|
252
|
+
CrazyGames gameplay tracking for free.
|
|
253
|
+
- Ads shown via `showAd()` automatically stop gameplay tracking for the
|
|
254
|
+
duration of the ad and resume it afterwards (only if gameplay was active
|
|
255
|
+
when the ad was requested).
|
|
256
|
+
- Calls are idempotent — duplicate starts or stops are not forwarded.
|
|
257
|
+
- Focus/tab changes are intentionally not tracked: CrazyGames handles those on
|
|
258
|
+
their side and instructs games not to signal them.
|
|
259
|
+
|
|
247
260
|
### Playgama
|
|
248
261
|
|
|
249
262
|
When running on Playgama, the SDK auto-initializes the Playgama Bridge and routes ads through it. No additional setup required.
|
package/dist/index.d.mts
CHANGED
|
@@ -823,6 +823,8 @@ declare class HyveClient {
|
|
|
823
823
|
configureAds(config: AdConfig): void;
|
|
824
824
|
/**
|
|
825
825
|
* Show an ad
|
|
826
|
+
* On CrazyGames, gameplay tracking is automatically stopped for the duration
|
|
827
|
+
* of the ad and resumed afterwards if it was active.
|
|
826
828
|
* @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
|
|
827
829
|
* @param placement Optional placement key, forwarded to the native AdMob path
|
|
828
830
|
* to resolve a per-placement unit ID. Ignored on the web (H5/Playgama) path.
|
|
@@ -1033,6 +1035,13 @@ declare global {
|
|
|
1033
1035
|
declare class CrazyGamesService {
|
|
1034
1036
|
private initialized;
|
|
1035
1037
|
private environment;
|
|
1038
|
+
/**
|
|
1039
|
+
* Whether gameplay is currently marked active on the CrazyGames side.
|
|
1040
|
+
* Makes gameplayStart/gameplayStop idempotent and lets ad flows restore the
|
|
1041
|
+
* pre-ad state. Focus/tab changes are intentionally NOT tracked — CrazyGames
|
|
1042
|
+
* handles those on their side (per docs.crazygames.com/sdk/game).
|
|
1043
|
+
*/
|
|
1044
|
+
private gameplayActive;
|
|
1036
1045
|
/**
|
|
1037
1046
|
* Detects if the game is running on the CrazyGames platform.
|
|
1038
1047
|
* Games on CrazyGames run inside an iframe, so we check document.referrer
|
|
@@ -1065,11 +1074,14 @@ declare class CrazyGamesService {
|
|
|
1065
1074
|
/**
|
|
1066
1075
|
* Notifies CrazyGames that gameplay has started.
|
|
1067
1076
|
* Call when the player actively begins or resumes playing.
|
|
1077
|
+
* Idempotent — repeated calls while gameplay is already active are no-ops.
|
|
1068
1078
|
*/
|
|
1069
1079
|
gameplayStart(): void;
|
|
1070
1080
|
/**
|
|
1071
1081
|
* Notifies CrazyGames that gameplay has stopped.
|
|
1072
|
-
* Call during menu access, level completion, or pausing.
|
|
1082
|
+
* Call during menu access, level completion, or pausing. Do NOT call on
|
|
1083
|
+
* focus/tab changes — CrazyGames handles those on their side.
|
|
1084
|
+
* Idempotent — repeated calls while gameplay is already stopped are no-ops.
|
|
1073
1085
|
*/
|
|
1074
1086
|
gameplayStop(): void;
|
|
1075
1087
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -823,6 +823,8 @@ declare class HyveClient {
|
|
|
823
823
|
configureAds(config: AdConfig): void;
|
|
824
824
|
/**
|
|
825
825
|
* Show an ad
|
|
826
|
+
* On CrazyGames, gameplay tracking is automatically stopped for the duration
|
|
827
|
+
* of the ad and resumed afterwards if it was active.
|
|
826
828
|
* @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
|
|
827
829
|
* @param placement Optional placement key, forwarded to the native AdMob path
|
|
828
830
|
* to resolve a per-placement unit ID. Ignored on the web (H5/Playgama) path.
|
|
@@ -1033,6 +1035,13 @@ declare global {
|
|
|
1033
1035
|
declare class CrazyGamesService {
|
|
1034
1036
|
private initialized;
|
|
1035
1037
|
private environment;
|
|
1038
|
+
/**
|
|
1039
|
+
* Whether gameplay is currently marked active on the CrazyGames side.
|
|
1040
|
+
* Makes gameplayStart/gameplayStop idempotent and lets ad flows restore the
|
|
1041
|
+
* pre-ad state. Focus/tab changes are intentionally NOT tracked — CrazyGames
|
|
1042
|
+
* handles those on their side (per docs.crazygames.com/sdk/game).
|
|
1043
|
+
*/
|
|
1044
|
+
private gameplayActive;
|
|
1036
1045
|
/**
|
|
1037
1046
|
* Detects if the game is running on the CrazyGames platform.
|
|
1038
1047
|
* Games on CrazyGames run inside an iframe, so we check document.referrer
|
|
@@ -1065,11 +1074,14 @@ declare class CrazyGamesService {
|
|
|
1065
1074
|
/**
|
|
1066
1075
|
* Notifies CrazyGames that gameplay has started.
|
|
1067
1076
|
* Call when the player actively begins or resumes playing.
|
|
1077
|
+
* Idempotent — repeated calls while gameplay is already active are no-ops.
|
|
1068
1078
|
*/
|
|
1069
1079
|
gameplayStart(): void;
|
|
1070
1080
|
/**
|
|
1071
1081
|
* Notifies CrazyGames that gameplay has stopped.
|
|
1072
|
-
* Call during menu access, level completion, or pausing.
|
|
1082
|
+
* Call during menu access, level completion, or pausing. Do NOT call on
|
|
1083
|
+
* focus/tab changes — CrazyGames handles those on their side.
|
|
1084
|
+
* Idempotent — repeated calls while gameplay is already stopped are no-ops.
|
|
1073
1085
|
*/
|
|
1074
1086
|
gameplayStop(): void;
|
|
1075
1087
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1243,6 +1243,13 @@ var CRAZYGAMES_SDK_CDN = "https://sdk.crazygames.com/crazygames-sdk-v3.js";
|
|
|
1243
1243
|
var CrazyGamesService = class {
|
|
1244
1244
|
initialized = false;
|
|
1245
1245
|
environment = null;
|
|
1246
|
+
/**
|
|
1247
|
+
* Whether gameplay is currently marked active on the CrazyGames side.
|
|
1248
|
+
* Makes gameplayStart/gameplayStop idempotent and lets ad flows restore the
|
|
1249
|
+
* pre-ad state. Focus/tab changes are intentionally NOT tracked — CrazyGames
|
|
1250
|
+
* handles those on their side (per docs.crazygames.com/sdk/game).
|
|
1251
|
+
*/
|
|
1252
|
+
gameplayActive = false;
|
|
1246
1253
|
/**
|
|
1247
1254
|
* Detects if the game is running on the CrazyGames platform.
|
|
1248
1255
|
* Games on CrazyGames run inside an iframe, so we check document.referrer
|
|
@@ -1317,6 +1324,8 @@ var CrazyGamesService = class {
|
|
|
1317
1324
|
completedAt: Date.now()
|
|
1318
1325
|
};
|
|
1319
1326
|
}
|
|
1327
|
+
const resumeAfterAd = this.gameplayActive;
|
|
1328
|
+
this.gameplayStop();
|
|
1320
1329
|
return new Promise((resolve) => {
|
|
1321
1330
|
sdk.ad.requestAd("midgame", {
|
|
1322
1331
|
adStarted: () => {
|
|
@@ -1324,10 +1333,12 @@ var CrazyGamesService = class {
|
|
|
1324
1333
|
},
|
|
1325
1334
|
adFinished: () => {
|
|
1326
1335
|
callbacks?.onAfterAd?.();
|
|
1336
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1327
1337
|
resolve({ success: true, type: "interstitial", requestedAt, completedAt: Date.now() });
|
|
1328
1338
|
},
|
|
1329
1339
|
adError: (error) => {
|
|
1330
1340
|
callbacks?.onAfterAd?.();
|
|
1341
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1331
1342
|
resolve({
|
|
1332
1343
|
success: false,
|
|
1333
1344
|
type: "interstitial",
|
|
@@ -1355,6 +1366,8 @@ var CrazyGamesService = class {
|
|
|
1355
1366
|
completedAt: Date.now()
|
|
1356
1367
|
};
|
|
1357
1368
|
}
|
|
1369
|
+
const resumeAfterAd = this.gameplayActive;
|
|
1370
|
+
this.gameplayStop();
|
|
1358
1371
|
return new Promise((resolve) => {
|
|
1359
1372
|
sdk.ad.requestAd("rewarded", {
|
|
1360
1373
|
adStarted: () => {
|
|
@@ -1363,10 +1376,12 @@ var CrazyGamesService = class {
|
|
|
1363
1376
|
adFinished: () => {
|
|
1364
1377
|
callbacks?.onRewardEarned?.();
|
|
1365
1378
|
callbacks?.onAfterAd?.();
|
|
1379
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1366
1380
|
resolve({ success: true, type: "rewarded", requestedAt, completedAt: Date.now() });
|
|
1367
1381
|
},
|
|
1368
1382
|
adError: (error) => {
|
|
1369
1383
|
callbacks?.onAfterAd?.();
|
|
1384
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1370
1385
|
resolve({
|
|
1371
1386
|
success: false,
|
|
1372
1387
|
type: "rewarded",
|
|
@@ -1381,17 +1396,22 @@ var CrazyGamesService = class {
|
|
|
1381
1396
|
/**
|
|
1382
1397
|
* Notifies CrazyGames that gameplay has started.
|
|
1383
1398
|
* Call when the player actively begins or resumes playing.
|
|
1399
|
+
* Idempotent — repeated calls while gameplay is already active are no-ops.
|
|
1384
1400
|
*/
|
|
1385
1401
|
gameplayStart() {
|
|
1386
|
-
if (!this.initialized) return;
|
|
1402
|
+
if (!this.initialized || this.gameplayActive) return;
|
|
1403
|
+
this.gameplayActive = true;
|
|
1387
1404
|
window.CrazyGames?.SDK.game.gameplayStart();
|
|
1388
1405
|
}
|
|
1389
1406
|
/**
|
|
1390
1407
|
* Notifies CrazyGames that gameplay has stopped.
|
|
1391
|
-
* Call during menu access, level completion, or pausing.
|
|
1408
|
+
* Call during menu access, level completion, or pausing. Do NOT call on
|
|
1409
|
+
* focus/tab changes — CrazyGames handles those on their side.
|
|
1410
|
+
* Idempotent — repeated calls while gameplay is already stopped are no-ops.
|
|
1392
1411
|
*/
|
|
1393
1412
|
gameplayStop() {
|
|
1394
|
-
if (!this.initialized) return;
|
|
1413
|
+
if (!this.initialized || !this.gameplayActive) return;
|
|
1414
|
+
this.gameplayActive = false;
|
|
1395
1415
|
window.CrazyGames?.SDK.game.gameplayStop();
|
|
1396
1416
|
}
|
|
1397
1417
|
/**
|
|
@@ -3080,6 +3100,8 @@ var HyveClient = class {
|
|
|
3080
3100
|
}
|
|
3081
3101
|
/**
|
|
3082
3102
|
* Show an ad
|
|
3103
|
+
* On CrazyGames, gameplay tracking is automatically stopped for the duration
|
|
3104
|
+
* of the ad and resumed afterwards if it was active.
|
|
3083
3105
|
* @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
|
|
3084
3106
|
* @param placement Optional placement key, forwarded to the native AdMob path
|
|
3085
3107
|
* to resolve a per-placement unit ID. Ignored on the web (H5/Playgama) path.
|
package/dist/index.mjs
CHANGED
|
@@ -1202,6 +1202,13 @@ var CRAZYGAMES_SDK_CDN = "https://sdk.crazygames.com/crazygames-sdk-v3.js";
|
|
|
1202
1202
|
var CrazyGamesService = class {
|
|
1203
1203
|
initialized = false;
|
|
1204
1204
|
environment = null;
|
|
1205
|
+
/**
|
|
1206
|
+
* Whether gameplay is currently marked active on the CrazyGames side.
|
|
1207
|
+
* Makes gameplayStart/gameplayStop idempotent and lets ad flows restore the
|
|
1208
|
+
* pre-ad state. Focus/tab changes are intentionally NOT tracked — CrazyGames
|
|
1209
|
+
* handles those on their side (per docs.crazygames.com/sdk/game).
|
|
1210
|
+
*/
|
|
1211
|
+
gameplayActive = false;
|
|
1205
1212
|
/**
|
|
1206
1213
|
* Detects if the game is running on the CrazyGames platform.
|
|
1207
1214
|
* Games on CrazyGames run inside an iframe, so we check document.referrer
|
|
@@ -1276,6 +1283,8 @@ var CrazyGamesService = class {
|
|
|
1276
1283
|
completedAt: Date.now()
|
|
1277
1284
|
};
|
|
1278
1285
|
}
|
|
1286
|
+
const resumeAfterAd = this.gameplayActive;
|
|
1287
|
+
this.gameplayStop();
|
|
1279
1288
|
return new Promise((resolve) => {
|
|
1280
1289
|
sdk.ad.requestAd("midgame", {
|
|
1281
1290
|
adStarted: () => {
|
|
@@ -1283,10 +1292,12 @@ var CrazyGamesService = class {
|
|
|
1283
1292
|
},
|
|
1284
1293
|
adFinished: () => {
|
|
1285
1294
|
callbacks?.onAfterAd?.();
|
|
1295
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1286
1296
|
resolve({ success: true, type: "interstitial", requestedAt, completedAt: Date.now() });
|
|
1287
1297
|
},
|
|
1288
1298
|
adError: (error) => {
|
|
1289
1299
|
callbacks?.onAfterAd?.();
|
|
1300
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1290
1301
|
resolve({
|
|
1291
1302
|
success: false,
|
|
1292
1303
|
type: "interstitial",
|
|
@@ -1314,6 +1325,8 @@ var CrazyGamesService = class {
|
|
|
1314
1325
|
completedAt: Date.now()
|
|
1315
1326
|
};
|
|
1316
1327
|
}
|
|
1328
|
+
const resumeAfterAd = this.gameplayActive;
|
|
1329
|
+
this.gameplayStop();
|
|
1317
1330
|
return new Promise((resolve) => {
|
|
1318
1331
|
sdk.ad.requestAd("rewarded", {
|
|
1319
1332
|
adStarted: () => {
|
|
@@ -1322,10 +1335,12 @@ var CrazyGamesService = class {
|
|
|
1322
1335
|
adFinished: () => {
|
|
1323
1336
|
callbacks?.onRewardEarned?.();
|
|
1324
1337
|
callbacks?.onAfterAd?.();
|
|
1338
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1325
1339
|
resolve({ success: true, type: "rewarded", requestedAt, completedAt: Date.now() });
|
|
1326
1340
|
},
|
|
1327
1341
|
adError: (error) => {
|
|
1328
1342
|
callbacks?.onAfterAd?.();
|
|
1343
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1329
1344
|
resolve({
|
|
1330
1345
|
success: false,
|
|
1331
1346
|
type: "rewarded",
|
|
@@ -1340,17 +1355,22 @@ var CrazyGamesService = class {
|
|
|
1340
1355
|
/**
|
|
1341
1356
|
* Notifies CrazyGames that gameplay has started.
|
|
1342
1357
|
* Call when the player actively begins or resumes playing.
|
|
1358
|
+
* Idempotent — repeated calls while gameplay is already active are no-ops.
|
|
1343
1359
|
*/
|
|
1344
1360
|
gameplayStart() {
|
|
1345
|
-
if (!this.initialized) return;
|
|
1361
|
+
if (!this.initialized || this.gameplayActive) return;
|
|
1362
|
+
this.gameplayActive = true;
|
|
1346
1363
|
window.CrazyGames?.SDK.game.gameplayStart();
|
|
1347
1364
|
}
|
|
1348
1365
|
/**
|
|
1349
1366
|
* Notifies CrazyGames that gameplay has stopped.
|
|
1350
|
-
* Call during menu access, level completion, or pausing.
|
|
1367
|
+
* Call during menu access, level completion, or pausing. Do NOT call on
|
|
1368
|
+
* focus/tab changes — CrazyGames handles those on their side.
|
|
1369
|
+
* Idempotent — repeated calls while gameplay is already stopped are no-ops.
|
|
1351
1370
|
*/
|
|
1352
1371
|
gameplayStop() {
|
|
1353
|
-
if (!this.initialized) return;
|
|
1372
|
+
if (!this.initialized || !this.gameplayActive) return;
|
|
1373
|
+
this.gameplayActive = false;
|
|
1354
1374
|
window.CrazyGames?.SDK.game.gameplayStop();
|
|
1355
1375
|
}
|
|
1356
1376
|
/**
|
|
@@ -3039,6 +3059,8 @@ var HyveClient = class {
|
|
|
3039
3059
|
}
|
|
3040
3060
|
/**
|
|
3041
3061
|
* Show an ad
|
|
3062
|
+
* On CrazyGames, gameplay tracking is automatically stopped for the duration
|
|
3063
|
+
* of the ad and resumed afterwards if it was active.
|
|
3042
3064
|
* @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
|
|
3043
3065
|
* @param placement Optional placement key, forwarded to the native AdMob path
|
|
3044
3066
|
* to resolve a per-placement unit ID. Ignored on the web (H5/Playgama) path.
|
package/dist/react.d.mts
CHANGED
|
@@ -554,6 +554,8 @@ declare class HyveClient {
|
|
|
554
554
|
configureAds(config: AdConfig): void;
|
|
555
555
|
/**
|
|
556
556
|
* Show an ad
|
|
557
|
+
* On CrazyGames, gameplay tracking is automatically stopped for the duration
|
|
558
|
+
* of the ad and resumed afterwards if it was active.
|
|
557
559
|
* @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
|
|
558
560
|
* @param placement Optional placement key, forwarded to the native AdMob path
|
|
559
561
|
* to resolve a per-placement unit ID. Ignored on the web (H5/Playgama) path.
|
package/dist/react.d.ts
CHANGED
|
@@ -554,6 +554,8 @@ declare class HyveClient {
|
|
|
554
554
|
configureAds(config: AdConfig): void;
|
|
555
555
|
/**
|
|
556
556
|
* Show an ad
|
|
557
|
+
* On CrazyGames, gameplay tracking is automatically stopped for the duration
|
|
558
|
+
* of the ad and resumed afterwards if it was active.
|
|
557
559
|
* @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
|
|
558
560
|
* @param placement Optional placement key, forwarded to the native AdMob path
|
|
559
561
|
* to resolve a per-placement unit ID. Ignored on the web (H5/Playgama) path.
|
package/dist/react.js
CHANGED
|
@@ -1200,6 +1200,13 @@ var CRAZYGAMES_SDK_CDN = "https://sdk.crazygames.com/crazygames-sdk-v3.js";
|
|
|
1200
1200
|
var CrazyGamesService = class {
|
|
1201
1201
|
initialized = false;
|
|
1202
1202
|
environment = null;
|
|
1203
|
+
/**
|
|
1204
|
+
* Whether gameplay is currently marked active on the CrazyGames side.
|
|
1205
|
+
* Makes gameplayStart/gameplayStop idempotent and lets ad flows restore the
|
|
1206
|
+
* pre-ad state. Focus/tab changes are intentionally NOT tracked — CrazyGames
|
|
1207
|
+
* handles those on their side (per docs.crazygames.com/sdk/game).
|
|
1208
|
+
*/
|
|
1209
|
+
gameplayActive = false;
|
|
1203
1210
|
/**
|
|
1204
1211
|
* Detects if the game is running on the CrazyGames platform.
|
|
1205
1212
|
* Games on CrazyGames run inside an iframe, so we check document.referrer
|
|
@@ -1274,6 +1281,8 @@ var CrazyGamesService = class {
|
|
|
1274
1281
|
completedAt: Date.now()
|
|
1275
1282
|
};
|
|
1276
1283
|
}
|
|
1284
|
+
const resumeAfterAd = this.gameplayActive;
|
|
1285
|
+
this.gameplayStop();
|
|
1277
1286
|
return new Promise((resolve) => {
|
|
1278
1287
|
sdk.ad.requestAd("midgame", {
|
|
1279
1288
|
adStarted: () => {
|
|
@@ -1281,10 +1290,12 @@ var CrazyGamesService = class {
|
|
|
1281
1290
|
},
|
|
1282
1291
|
adFinished: () => {
|
|
1283
1292
|
callbacks?.onAfterAd?.();
|
|
1293
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1284
1294
|
resolve({ success: true, type: "interstitial", requestedAt, completedAt: Date.now() });
|
|
1285
1295
|
},
|
|
1286
1296
|
adError: (error) => {
|
|
1287
1297
|
callbacks?.onAfterAd?.();
|
|
1298
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1288
1299
|
resolve({
|
|
1289
1300
|
success: false,
|
|
1290
1301
|
type: "interstitial",
|
|
@@ -1312,6 +1323,8 @@ var CrazyGamesService = class {
|
|
|
1312
1323
|
completedAt: Date.now()
|
|
1313
1324
|
};
|
|
1314
1325
|
}
|
|
1326
|
+
const resumeAfterAd = this.gameplayActive;
|
|
1327
|
+
this.gameplayStop();
|
|
1315
1328
|
return new Promise((resolve) => {
|
|
1316
1329
|
sdk.ad.requestAd("rewarded", {
|
|
1317
1330
|
adStarted: () => {
|
|
@@ -1320,10 +1333,12 @@ var CrazyGamesService = class {
|
|
|
1320
1333
|
adFinished: () => {
|
|
1321
1334
|
callbacks?.onRewardEarned?.();
|
|
1322
1335
|
callbacks?.onAfterAd?.();
|
|
1336
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1323
1337
|
resolve({ success: true, type: "rewarded", requestedAt, completedAt: Date.now() });
|
|
1324
1338
|
},
|
|
1325
1339
|
adError: (error) => {
|
|
1326
1340
|
callbacks?.onAfterAd?.();
|
|
1341
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1327
1342
|
resolve({
|
|
1328
1343
|
success: false,
|
|
1329
1344
|
type: "rewarded",
|
|
@@ -1338,17 +1353,22 @@ var CrazyGamesService = class {
|
|
|
1338
1353
|
/**
|
|
1339
1354
|
* Notifies CrazyGames that gameplay has started.
|
|
1340
1355
|
* Call when the player actively begins or resumes playing.
|
|
1356
|
+
* Idempotent — repeated calls while gameplay is already active are no-ops.
|
|
1341
1357
|
*/
|
|
1342
1358
|
gameplayStart() {
|
|
1343
|
-
if (!this.initialized) return;
|
|
1359
|
+
if (!this.initialized || this.gameplayActive) return;
|
|
1360
|
+
this.gameplayActive = true;
|
|
1344
1361
|
window.CrazyGames?.SDK.game.gameplayStart();
|
|
1345
1362
|
}
|
|
1346
1363
|
/**
|
|
1347
1364
|
* Notifies CrazyGames that gameplay has stopped.
|
|
1348
|
-
* Call during menu access, level completion, or pausing.
|
|
1365
|
+
* Call during menu access, level completion, or pausing. Do NOT call on
|
|
1366
|
+
* focus/tab changes — CrazyGames handles those on their side.
|
|
1367
|
+
* Idempotent — repeated calls while gameplay is already stopped are no-ops.
|
|
1349
1368
|
*/
|
|
1350
1369
|
gameplayStop() {
|
|
1351
|
-
if (!this.initialized) return;
|
|
1370
|
+
if (!this.initialized || !this.gameplayActive) return;
|
|
1371
|
+
this.gameplayActive = false;
|
|
1352
1372
|
window.CrazyGames?.SDK.game.gameplayStop();
|
|
1353
1373
|
}
|
|
1354
1374
|
/**
|
|
@@ -3031,6 +3051,8 @@ var HyveClient = class {
|
|
|
3031
3051
|
}
|
|
3032
3052
|
/**
|
|
3033
3053
|
* Show an ad
|
|
3054
|
+
* On CrazyGames, gameplay tracking is automatically stopped for the duration
|
|
3055
|
+
* of the ad and resumed afterwards if it was active.
|
|
3034
3056
|
* @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
|
|
3035
3057
|
* @param placement Optional placement key, forwarded to the native AdMob path
|
|
3036
3058
|
* to resolve a per-placement unit ID. Ignored on the web (H5/Playgama) path.
|
package/dist/react.mjs
CHANGED
|
@@ -1178,6 +1178,13 @@ var CRAZYGAMES_SDK_CDN = "https://sdk.crazygames.com/crazygames-sdk-v3.js";
|
|
|
1178
1178
|
var CrazyGamesService = class {
|
|
1179
1179
|
initialized = false;
|
|
1180
1180
|
environment = null;
|
|
1181
|
+
/**
|
|
1182
|
+
* Whether gameplay is currently marked active on the CrazyGames side.
|
|
1183
|
+
* Makes gameplayStart/gameplayStop idempotent and lets ad flows restore the
|
|
1184
|
+
* pre-ad state. Focus/tab changes are intentionally NOT tracked — CrazyGames
|
|
1185
|
+
* handles those on their side (per docs.crazygames.com/sdk/game).
|
|
1186
|
+
*/
|
|
1187
|
+
gameplayActive = false;
|
|
1181
1188
|
/**
|
|
1182
1189
|
* Detects if the game is running on the CrazyGames platform.
|
|
1183
1190
|
* Games on CrazyGames run inside an iframe, so we check document.referrer
|
|
@@ -1252,6 +1259,8 @@ var CrazyGamesService = class {
|
|
|
1252
1259
|
completedAt: Date.now()
|
|
1253
1260
|
};
|
|
1254
1261
|
}
|
|
1262
|
+
const resumeAfterAd = this.gameplayActive;
|
|
1263
|
+
this.gameplayStop();
|
|
1255
1264
|
return new Promise((resolve) => {
|
|
1256
1265
|
sdk.ad.requestAd("midgame", {
|
|
1257
1266
|
adStarted: () => {
|
|
@@ -1259,10 +1268,12 @@ var CrazyGamesService = class {
|
|
|
1259
1268
|
},
|
|
1260
1269
|
adFinished: () => {
|
|
1261
1270
|
callbacks?.onAfterAd?.();
|
|
1271
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1262
1272
|
resolve({ success: true, type: "interstitial", requestedAt, completedAt: Date.now() });
|
|
1263
1273
|
},
|
|
1264
1274
|
adError: (error) => {
|
|
1265
1275
|
callbacks?.onAfterAd?.();
|
|
1276
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1266
1277
|
resolve({
|
|
1267
1278
|
success: false,
|
|
1268
1279
|
type: "interstitial",
|
|
@@ -1290,6 +1301,8 @@ var CrazyGamesService = class {
|
|
|
1290
1301
|
completedAt: Date.now()
|
|
1291
1302
|
};
|
|
1292
1303
|
}
|
|
1304
|
+
const resumeAfterAd = this.gameplayActive;
|
|
1305
|
+
this.gameplayStop();
|
|
1293
1306
|
return new Promise((resolve) => {
|
|
1294
1307
|
sdk.ad.requestAd("rewarded", {
|
|
1295
1308
|
adStarted: () => {
|
|
@@ -1298,10 +1311,12 @@ var CrazyGamesService = class {
|
|
|
1298
1311
|
adFinished: () => {
|
|
1299
1312
|
callbacks?.onRewardEarned?.();
|
|
1300
1313
|
callbacks?.onAfterAd?.();
|
|
1314
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1301
1315
|
resolve({ success: true, type: "rewarded", requestedAt, completedAt: Date.now() });
|
|
1302
1316
|
},
|
|
1303
1317
|
adError: (error) => {
|
|
1304
1318
|
callbacks?.onAfterAd?.();
|
|
1319
|
+
if (resumeAfterAd) this.gameplayStart();
|
|
1305
1320
|
resolve({
|
|
1306
1321
|
success: false,
|
|
1307
1322
|
type: "rewarded",
|
|
@@ -1316,17 +1331,22 @@ var CrazyGamesService = class {
|
|
|
1316
1331
|
/**
|
|
1317
1332
|
* Notifies CrazyGames that gameplay has started.
|
|
1318
1333
|
* Call when the player actively begins or resumes playing.
|
|
1334
|
+
* Idempotent — repeated calls while gameplay is already active are no-ops.
|
|
1319
1335
|
*/
|
|
1320
1336
|
gameplayStart() {
|
|
1321
|
-
if (!this.initialized) return;
|
|
1337
|
+
if (!this.initialized || this.gameplayActive) return;
|
|
1338
|
+
this.gameplayActive = true;
|
|
1322
1339
|
window.CrazyGames?.SDK.game.gameplayStart();
|
|
1323
1340
|
}
|
|
1324
1341
|
/**
|
|
1325
1342
|
* Notifies CrazyGames that gameplay has stopped.
|
|
1326
|
-
* Call during menu access, level completion, or pausing.
|
|
1343
|
+
* Call during menu access, level completion, or pausing. Do NOT call on
|
|
1344
|
+
* focus/tab changes — CrazyGames handles those on their side.
|
|
1345
|
+
* Idempotent — repeated calls while gameplay is already stopped are no-ops.
|
|
1327
1346
|
*/
|
|
1328
1347
|
gameplayStop() {
|
|
1329
|
-
if (!this.initialized) return;
|
|
1348
|
+
if (!this.initialized || !this.gameplayActive) return;
|
|
1349
|
+
this.gameplayActive = false;
|
|
1330
1350
|
window.CrazyGames?.SDK.game.gameplayStop();
|
|
1331
1351
|
}
|
|
1332
1352
|
/**
|
|
@@ -3009,6 +3029,8 @@ var HyveClient = class {
|
|
|
3009
3029
|
}
|
|
3010
3030
|
/**
|
|
3011
3031
|
* Show an ad
|
|
3032
|
+
* On CrazyGames, gameplay tracking is automatically stopped for the duration
|
|
3033
|
+
* of the ad and resumed afterwards if it was active.
|
|
3012
3034
|
* @param type Type of ad to show ('rewarded', 'interstitial', or 'preroll')
|
|
3013
3035
|
* @param placement Optional placement key, forwarded to the native AdMob path
|
|
3014
3036
|
* to resolve a per-placement unit ID. Ignored on the web (H5/Playgama) path.
|