@ak--47/dungeon-master 1.0.0 → 1.1.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 +7 -7
- package/dungeons/technical/ad-spend-schema.json +128 -0
- package/dungeons/technical/ad-spend.js +116 -0
- package/dungeons/technical/anonymous-users-schema.json +91 -0
- package/dungeons/technical/anonymous-users.js +102 -0
- package/dungeons/technical/array-of-object-lookup-schema.json +191 -0
- package/dungeons/{array-of-object-lookup.js → technical/array-of-object-lookup.js} +11 -4
- package/dungeons/technical/experiments-schema.json +197 -0
- package/dungeons/technical/experiments.js +168 -0
- package/dungeons/technical/foobar-schema.json +362 -0
- package/dungeons/{foobar.js → technical/foobar.js} +2 -2
- package/dungeons/technical/group-analytics-schema.json +149 -0
- package/dungeons/technical/group-analytics.js +151 -0
- package/dungeons/technical/mirror-strategies-schema.json +84 -0
- package/dungeons/technical/mirror-strategies.js +126 -0
- package/dungeons/technical/nested-objects-schema.json +145 -0
- package/dungeons/technical/nested-objects.js +207 -0
- package/dungeons/technical/retention-cadence-schema.json +37 -0
- package/dungeons/{retention-cadence.js → technical/retention-cadence.js} +1 -1
- package/dungeons/technical/sanity-schema.json +185 -0
- package/dungeons/{sanity.js → technical/sanity.js} +3 -2
- package/dungeons/technical/scale-test-schema.json +70 -0
- package/dungeons/technical/scale-test.js +90 -0
- package/dungeons/technical/scd-schema.json +270 -0
- package/dungeons/{scd.js → technical/scd.js} +19 -10
- package/dungeons/technical/simple-schema.json +278 -0
- package/dungeons/{simple.js → technical/simple.js} +6 -6
- package/dungeons/technical/simplest-schema.json +635 -0
- package/dungeons/{simplest.js → technical/simplest.js} +6 -6
- package/dungeons/technical/text-generation-schema.json +1059 -0
- package/dungeons/{text-generation.js → technical/text-generation.js} +23 -9
- package/dungeons/vertical/community-schema.json +557 -0
- package/dungeons/vertical/community.js +788 -0
- package/dungeons/vertical/devtools-schema.json +580 -0
- package/dungeons/vertical/devtools.js +837 -0
- package/dungeons/vertical/ecommerce-schema.json +586 -0
- package/dungeons/{ecommerce.js → vertical/ecommerce.js} +34 -3
- package/dungeons/vertical/education-schema.json +697 -0
- package/dungeons/{education.js → vertical/education.js} +54 -36
- package/dungeons/vertical/fintech-schema.json +563 -0
- package/dungeons/{fintech.js → vertical/fintech.js} +91 -53
- package/dungeons/vertical/fitness-schema.json +508 -0
- package/dungeons/vertical/fitness.js +802 -0
- package/dungeons/vertical/food-delivery-schema.json +678 -0
- package/dungeons/{food.js → vertical/food-delivery.js} +51 -23
- package/dungeons/vertical/gaming-schema.json +394 -0
- package/dungeons/{gaming.js → vertical/gaming.js} +9 -7
- package/dungeons/vertical/healthcare-schema.json +527 -0
- package/dungeons/vertical/healthcare.js +769 -0
- package/dungeons/vertical/insurance-application-schema.json +466 -0
- package/dungeons/{insurance-application.js → vertical/insurance-application.js} +33 -29
- package/dungeons/vertical/logistics-schema.json +552 -0
- package/dungeons/vertical/logistics.js +793 -0
- package/dungeons/vertical/marketplace-schema.json +511 -0
- package/dungeons/vertical/marketplace.js +844 -0
- package/dungeons/vertical/media-schema.json +787 -0
- package/dungeons/{media.js → vertical/media.js} +94 -16
- package/dungeons/vertical/rpg-schema.json +654 -0
- package/dungeons/{rpg.js → vertical/rpg.js} +78 -57
- package/dungeons/vertical/sass-schema.json +653 -0
- package/dungeons/{sass.js → vertical/sass.js} +49 -23
- package/dungeons/vertical/social-schema.json +552 -0
- package/dungeons/{social.js → vertical/social.js} +60 -14
- package/dungeons/vertical/travel-schema.json +558 -0
- package/dungeons/vertical/travel.js +736 -0
- package/index.js +19 -15
- package/lib/core/config-validator.js +286 -1
- package/lib/core/context.js +7 -5
- package/lib/generators/adspend.js +3 -3
- package/lib/generators/events.js +141 -14
- package/lib/generators/funnels.js +67 -7
- package/lib/generators/text.js +2 -2
- package/lib/orchestrators/user-loop.js +441 -22
- package/lib/templates/soup-presets.js +2 -2
- package/lib/utils/utils.js +4 -5
- package/package.json +4 -3
- package/scripts/dungeon-to-json.mjs +163 -0
- package/scripts/extract-dungeon-schema.mjs +297 -0
- package/scripts/json-to-dungeon.mjs +200 -0
- package/scripts/run-dungeon.mjs +76 -0
- package/scripts/run-many.mjs +118 -0
- package/scripts/verify-runner.mjs +42 -0
- package/types.d.ts +313 -1
- package/dungeons/array-of-object-lookup-schema.json +0 -327
- package/dungeons/ecommerce-schema.json +0 -462
- package/dungeons/education-schema.json +0 -2409
- package/dungeons/fintech-schema.json +0 -14034
- package/dungeons/foobar-schema.json +0 -403
- package/dungeons/food-delivery-schema.json +0 -192
- package/dungeons/food-delivery.js +0 -602
- package/dungeons/food-schema.json +0 -1152
- package/dungeons/gaming-schema.json +0 -1270
- package/dungeons/insurance-application-schema.json +0 -204
- package/dungeons/media-schema.json +0 -906
- package/dungeons/retention-cadence-schema.json +0 -78
- package/dungeons/rpg-schema.json +0 -4526
- package/dungeons/sanity-schema.json +0 -255
- package/dungeons/sass-schema.json +0 -1291
- package/dungeons/scd-schema.json +0 -919
- package/dungeons/simple-schema.json +0 -608
- package/dungeons/simplest-schema.json +0 -1418
- package/dungeons/social-schema.json +0 -1118
- package/dungeons/text-generation-schema.json +0 -3096
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import dayjs from "dayjs";
|
|
2
2
|
import utc from "dayjs/plugin/utc.js";
|
|
3
3
|
import "dotenv/config";
|
|
4
|
-
import * as u from "
|
|
4
|
+
import * as u from "../../lib/utils/utils.js";
|
|
5
5
|
import * as v from "ak-tools";
|
|
6
6
|
|
|
7
7
|
const SEED = "harness-gaming";
|
|
@@ -211,7 +211,7 @@ const config = {
|
|
|
211
211
|
timeToConvert: 2,
|
|
212
212
|
weight: 4,
|
|
213
213
|
props: {
|
|
214
|
-
"dungeon_id":
|
|
214
|
+
"dungeon_id": dungeonIds,
|
|
215
215
|
"difficulty": ["Easy", "Medium", "Hard", "Deadly"],
|
|
216
216
|
}
|
|
217
217
|
},
|
|
@@ -221,7 +221,7 @@ const config = {
|
|
|
221
221
|
conversionRate: 55,
|
|
222
222
|
timeToConvert: 3,
|
|
223
223
|
weight: 3,
|
|
224
|
-
props: { "quest_id":
|
|
224
|
+
props: { "quest_id": questIds },
|
|
225
225
|
},
|
|
226
226
|
{
|
|
227
227
|
// Preparation before dungeon: inspect + search for strategic explorer hook
|
|
@@ -274,14 +274,14 @@ const config = {
|
|
|
274
274
|
weight: 2,
|
|
275
275
|
properties: {
|
|
276
276
|
"completion_time_mins": u.weighNumRange(3, 25, 0.8, 10),
|
|
277
|
-
"skipped":
|
|
277
|
+
"skipped": [false, false, false, false, false, false, true],
|
|
278
278
|
}
|
|
279
279
|
},
|
|
280
280
|
{
|
|
281
281
|
event: "quest accepted",
|
|
282
282
|
weight: 15,
|
|
283
283
|
properties: {
|
|
284
|
-
"quest_id":
|
|
284
|
+
"quest_id": questIds,
|
|
285
285
|
"quest_type": [
|
|
286
286
|
"Main Story",
|
|
287
287
|
"Side Quest",
|
|
@@ -296,7 +296,7 @@ const config = {
|
|
|
296
296
|
event: "quest objective completed",
|
|
297
297
|
weight: 12,
|
|
298
298
|
properties: {
|
|
299
|
-
"quest_id":
|
|
299
|
+
"quest_id": questIds,
|
|
300
300
|
"objective_number": u.weighNumRange(1, 5),
|
|
301
301
|
}
|
|
302
302
|
},
|
|
@@ -304,16 +304,18 @@ const config = {
|
|
|
304
304
|
event: "quest turned in",
|
|
305
305
|
weight: 10,
|
|
306
306
|
properties: {
|
|
307
|
-
"quest_id":
|
|
307
|
+
"quest_id": questIds,
|
|
308
308
|
"reward_gold": u.weighNumRange(10, 500, 0.5, 100),
|
|
309
309
|
"reward_xp": u.weighNumRange(50, 2000, 0.5, 500),
|
|
310
|
+
"compass_user": [false],
|
|
311
|
+
"subscriber_advantage": ["Free"],
|
|
310
312
|
}
|
|
311
313
|
},
|
|
312
314
|
{
|
|
313
315
|
event: "enter dungeon",
|
|
314
316
|
weight: 18,
|
|
315
317
|
properties: {
|
|
316
|
-
"dungeon_id":
|
|
318
|
+
"dungeon_id": dungeonIds,
|
|
317
319
|
"difficulty": ["Easy", "Medium", "Hard", "Deadly"],
|
|
318
320
|
"party_size": u.weighNumRange(1, 5),
|
|
319
321
|
}
|
|
@@ -322,9 +324,12 @@ const config = {
|
|
|
322
324
|
event: "exit dungeon",
|
|
323
325
|
weight: 14,
|
|
324
326
|
properties: {
|
|
325
|
-
"dungeon_id":
|
|
327
|
+
"dungeon_id": dungeonIds,
|
|
326
328
|
"time_spent_mins": u.weighNumRange(5, 120, 0.6, 30),
|
|
327
329
|
"completion_status": ["completed", "abandoned", "died"],
|
|
330
|
+
"strategic_explorer": [false],
|
|
331
|
+
"legendary_weapon_equipped": [false],
|
|
332
|
+
"subscriber_advantage": ["Free"],
|
|
328
333
|
}
|
|
329
334
|
},
|
|
330
335
|
{
|
|
@@ -340,6 +345,10 @@ const config = {
|
|
|
340
345
|
"Rare Artifact"
|
|
341
346
|
],
|
|
342
347
|
"treasure_value": u.weighNumRange(5, 1000, 1.2, 50),
|
|
348
|
+
"legendary_drop": [false],
|
|
349
|
+
"strategic_explorer": [false],
|
|
350
|
+
"subscriber_advantage": ["Free"],
|
|
351
|
+
"elite_bonus": [false],
|
|
343
352
|
}
|
|
344
353
|
},
|
|
345
354
|
{
|
|
@@ -354,7 +363,10 @@ const config = {
|
|
|
354
363
|
"Friendly Fire"
|
|
355
364
|
],
|
|
356
365
|
"player_level": u.weighNumRange(1, 50),
|
|
357
|
-
"resurrection_used":
|
|
366
|
+
"resurrection_used": [false, false, false, true],
|
|
367
|
+
"cursed_week": [false],
|
|
368
|
+
"near_death_survival": [false],
|
|
369
|
+
"subscriber_advantage": ["Free"],
|
|
358
370
|
}
|
|
359
371
|
},
|
|
360
372
|
{
|
|
@@ -369,7 +381,7 @@ const config = {
|
|
|
369
381
|
event: "item purchased",
|
|
370
382
|
weight: 11,
|
|
371
383
|
properties: {
|
|
372
|
-
"item_id":
|
|
384
|
+
"item_id": itemIds,
|
|
373
385
|
"item_type": [
|
|
374
386
|
"Weapon",
|
|
375
387
|
"Armor",
|
|
@@ -386,7 +398,7 @@ const config = {
|
|
|
386
398
|
event: "item sold",
|
|
387
399
|
weight: 7,
|
|
388
400
|
properties: {
|
|
389
|
-
"item_id":
|
|
401
|
+
"item_id": itemIds,
|
|
390
402
|
"item_type": [
|
|
391
403
|
"Weapon",
|
|
392
404
|
"Armor",
|
|
@@ -409,8 +421,9 @@ const config = {
|
|
|
409
421
|
"Cosmetic Bundle",
|
|
410
422
|
"Season Pass"
|
|
411
423
|
],
|
|
412
|
-
"price_usd":
|
|
424
|
+
"price_usd": [4.99, 9.99, 19.99, 49.99, 99.99],
|
|
413
425
|
"payment_method": ["Credit Card", "PayPal", "Apple Pay", "Google Pay"],
|
|
426
|
+
"lucky_charm_effect": [false],
|
|
414
427
|
}
|
|
415
428
|
},
|
|
416
429
|
{
|
|
@@ -457,14 +470,14 @@ const config = {
|
|
|
457
470
|
"Quest Location",
|
|
458
471
|
"Town Square"
|
|
459
472
|
],
|
|
460
|
-
"clue_found":
|
|
473
|
+
"clue_found": [false, false, true, true, true],
|
|
461
474
|
}
|
|
462
475
|
},
|
|
463
476
|
{
|
|
464
477
|
event: "use item",
|
|
465
478
|
weight: 14,
|
|
466
479
|
properties: {
|
|
467
|
-
"item_id":
|
|
480
|
+
"item_id": itemIds,
|
|
468
481
|
"item_type": [
|
|
469
482
|
"Health Potion",
|
|
470
483
|
"Mana Potion",
|
|
@@ -497,7 +510,11 @@ const config = {
|
|
|
497
510
|
weight: 18,
|
|
498
511
|
properties: {
|
|
499
512
|
"outcome": ["Victory", "Defeat", "Fled"],
|
|
500
|
-
"loot_gained":
|
|
513
|
+
"loot_gained": [false, false, false, true, true, true, true, true, true, true],
|
|
514
|
+
"legendary_weapon_equipped": [false],
|
|
515
|
+
"subscriber_advantage": ["Free"],
|
|
516
|
+
"near_death_survival": [false],
|
|
517
|
+
"guild_member_retained": [false],
|
|
501
518
|
}
|
|
502
519
|
}
|
|
503
520
|
],
|
|
@@ -516,7 +533,7 @@ const config = {
|
|
|
516
533
|
"High",
|
|
517
534
|
"Ultra"
|
|
518
535
|
],
|
|
519
|
-
subscription_tier:
|
|
536
|
+
subscription_tier: ["Free", "Free", "Free", "Premium", "Elite"],
|
|
520
537
|
},
|
|
521
538
|
|
|
522
539
|
scdProps: {},
|
|
@@ -585,18 +602,16 @@ const config = {
|
|
|
585
602
|
if (EVENT_TIME.isAfter(CURSED_WEEK_START) && EVENT_TIME.isBefore(CURSED_WEEK_END)) {
|
|
586
603
|
// 50% chance to inject a death event
|
|
587
604
|
if (chance.bool({ likelihood: 30 })) {
|
|
588
|
-
|
|
589
|
-
event: "player death",
|
|
590
|
-
time: record.time,
|
|
591
|
-
user_id: record.user_id,
|
|
592
|
-
cause_of_death: "Curse",
|
|
593
|
-
player_level: chance.integer({ min: 1, max: 50 }),
|
|
594
|
-
resurrection_used: chance.bool({ likelihood: 80 }), // More res usage during curse
|
|
595
|
-
cursed_week: true,
|
|
596
|
-
};
|
|
597
|
-
// Return death event instead sometimes
|
|
605
|
+
// Return death event instead sometimes (clone from current record for schema)
|
|
598
606
|
if (chance.bool({ likelihood: 50 })) {
|
|
599
|
-
return
|
|
607
|
+
return {
|
|
608
|
+
...record,
|
|
609
|
+
event: "player death",
|
|
610
|
+
cause_of_death: "Curse",
|
|
611
|
+
player_level: chance.integer({ min: 1, max: 50 }),
|
|
612
|
+
resurrection_used: chance.bool({ likelihood: 80 }), // More res usage during curse
|
|
613
|
+
cursed_week: true,
|
|
614
|
+
};
|
|
600
615
|
}
|
|
601
616
|
}
|
|
602
617
|
}
|
|
@@ -715,9 +730,8 @@ const config = {
|
|
|
715
730
|
// Add extra quest completions for compass users
|
|
716
731
|
if (chance.bool({ likelihood: 40 })) {
|
|
717
732
|
const extraQuest = {
|
|
718
|
-
event
|
|
733
|
+
...event,
|
|
719
734
|
time: eventTime.add(chance.integer({ min: 10, max: 120 }), 'minutes').toISOString(),
|
|
720
|
-
user_id: event.user_id,
|
|
721
735
|
quest_id: chance.pickone(questIds),
|
|
722
736
|
reward_gold: chance.integer({ min: 100, max: 500 }),
|
|
723
737
|
reward_xp: chance.integer({ min: 500, max: 2000 }),
|
|
@@ -742,20 +756,23 @@ const config = {
|
|
|
742
756
|
|
|
743
757
|
// Add additional purchase events (higher LTV)
|
|
744
758
|
if (event.event === "item purchased" && chance.bool({ likelihood: 35 })) {
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
+
const purchaseTemplate = userEvents.find(e => e.event === "real money purchase");
|
|
760
|
+
if (purchaseTemplate) {
|
|
761
|
+
const extraPurchase = {
|
|
762
|
+
...purchaseTemplate,
|
|
763
|
+
time: eventTime.add(chance.integer({ min: 1, max: 3 }), 'days').toISOString(),
|
|
764
|
+
user_id: event.user_id,
|
|
765
|
+
product: chance.pickone([
|
|
766
|
+
"Premium Currency (5000)",
|
|
767
|
+
"Legendary Weapon Chest",
|
|
768
|
+
"Season Pass"
|
|
769
|
+
]),
|
|
770
|
+
price_usd: chance.pickone([19.99, 49.99, 99.99]),
|
|
771
|
+
payment_method: chance.pickone(["Credit Card", "PayPal"]),
|
|
772
|
+
lucky_charm_effect: true,
|
|
773
|
+
};
|
|
774
|
+
userEvents.splice(idx + 1, 0, extraPurchase);
|
|
775
|
+
}
|
|
759
776
|
}
|
|
760
777
|
}
|
|
761
778
|
|
|
@@ -863,17 +880,20 @@ const config = {
|
|
|
863
880
|
// Elite users get bonus engagement events
|
|
864
881
|
if (isElite && Math.random() * 100 < 15) {
|
|
865
882
|
if (event.event === "quest turned in" || event.event === "exit dungeon") {
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
883
|
+
const treasureTemplate = userEvents.find(e => e.event === "find treasure");
|
|
884
|
+
if (treasureTemplate) {
|
|
885
|
+
const treasureTypes = ["Rare Artifact", "Gold", "Weapon", "Armor"];
|
|
886
|
+
const bonusEvent = {
|
|
887
|
+
...treasureTemplate,
|
|
888
|
+
time: eventTime.add(Math.floor(Math.random() * 26) + 5, 'minutes').toISOString(),
|
|
889
|
+
user_id: event.user_id,
|
|
890
|
+
treasure_type: treasureTypes[Math.floor(Math.random() * treasureTypes.length)],
|
|
891
|
+
treasure_value: Math.floor(Math.random() * 601) + 200,
|
|
892
|
+
subscriber_advantage: "Elite",
|
|
893
|
+
elite_bonus: true,
|
|
894
|
+
};
|
|
895
|
+
userEvents.splice(idx + 1, 0, bonusEvent);
|
|
896
|
+
}
|
|
877
897
|
}
|
|
878
898
|
}
|
|
879
899
|
}
|
|
@@ -898,9 +918,10 @@ const config = {
|
|
|
898
918
|
} else if (joinedGuildEarly) {
|
|
899
919
|
// Add extra engagement events for retained users
|
|
900
920
|
const lastEvent = userEvents[userEvents.length - 1];
|
|
901
|
-
|
|
921
|
+
const combatTemplate = userEvents.find(e => e.event === "combat completed");
|
|
922
|
+
if (lastEvent && combatTemplate && chance.bool({ likelihood: 60 })) {
|
|
902
923
|
const retentionEvent = {
|
|
903
|
-
|
|
924
|
+
...combatTemplate,
|
|
904
925
|
time: dayjs(lastEvent.time).add(chance.integer({ min: 1, max: 5 }), 'days').toISOString(),
|
|
905
926
|
user_id: lastEvent.user_id,
|
|
906
927
|
outcome: "Victory",
|