@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.
Files changed (103) hide show
  1. package/README.md +7 -7
  2. package/dungeons/technical/ad-spend-schema.json +128 -0
  3. package/dungeons/technical/ad-spend.js +116 -0
  4. package/dungeons/technical/anonymous-users-schema.json +91 -0
  5. package/dungeons/technical/anonymous-users.js +102 -0
  6. package/dungeons/technical/array-of-object-lookup-schema.json +191 -0
  7. package/dungeons/{array-of-object-lookup.js → technical/array-of-object-lookup.js} +11 -4
  8. package/dungeons/technical/experiments-schema.json +197 -0
  9. package/dungeons/technical/experiments.js +168 -0
  10. package/dungeons/technical/foobar-schema.json +362 -0
  11. package/dungeons/{foobar.js → technical/foobar.js} +2 -2
  12. package/dungeons/technical/group-analytics-schema.json +149 -0
  13. package/dungeons/technical/group-analytics.js +151 -0
  14. package/dungeons/technical/mirror-strategies-schema.json +84 -0
  15. package/dungeons/technical/mirror-strategies.js +126 -0
  16. package/dungeons/technical/nested-objects-schema.json +145 -0
  17. package/dungeons/technical/nested-objects.js +207 -0
  18. package/dungeons/technical/retention-cadence-schema.json +37 -0
  19. package/dungeons/{retention-cadence.js → technical/retention-cadence.js} +1 -1
  20. package/dungeons/technical/sanity-schema.json +185 -0
  21. package/dungeons/{sanity.js → technical/sanity.js} +3 -2
  22. package/dungeons/technical/scale-test-schema.json +70 -0
  23. package/dungeons/technical/scale-test.js +90 -0
  24. package/dungeons/technical/scd-schema.json +270 -0
  25. package/dungeons/{scd.js → technical/scd.js} +19 -10
  26. package/dungeons/technical/simple-schema.json +278 -0
  27. package/dungeons/{simple.js → technical/simple.js} +6 -6
  28. package/dungeons/technical/simplest-schema.json +635 -0
  29. package/dungeons/{simplest.js → technical/simplest.js} +6 -6
  30. package/dungeons/technical/text-generation-schema.json +1059 -0
  31. package/dungeons/{text-generation.js → technical/text-generation.js} +23 -9
  32. package/dungeons/vertical/community-schema.json +557 -0
  33. package/dungeons/vertical/community.js +788 -0
  34. package/dungeons/vertical/devtools-schema.json +580 -0
  35. package/dungeons/vertical/devtools.js +837 -0
  36. package/dungeons/vertical/ecommerce-schema.json +586 -0
  37. package/dungeons/{ecommerce.js → vertical/ecommerce.js} +34 -3
  38. package/dungeons/vertical/education-schema.json +697 -0
  39. package/dungeons/{education.js → vertical/education.js} +54 -36
  40. package/dungeons/vertical/fintech-schema.json +563 -0
  41. package/dungeons/{fintech.js → vertical/fintech.js} +91 -53
  42. package/dungeons/vertical/fitness-schema.json +508 -0
  43. package/dungeons/vertical/fitness.js +802 -0
  44. package/dungeons/vertical/food-delivery-schema.json +678 -0
  45. package/dungeons/{food.js → vertical/food-delivery.js} +51 -23
  46. package/dungeons/vertical/gaming-schema.json +394 -0
  47. package/dungeons/{gaming.js → vertical/gaming.js} +9 -7
  48. package/dungeons/vertical/healthcare-schema.json +527 -0
  49. package/dungeons/vertical/healthcare.js +769 -0
  50. package/dungeons/vertical/insurance-application-schema.json +466 -0
  51. package/dungeons/{insurance-application.js → vertical/insurance-application.js} +33 -29
  52. package/dungeons/vertical/logistics-schema.json +552 -0
  53. package/dungeons/vertical/logistics.js +793 -0
  54. package/dungeons/vertical/marketplace-schema.json +511 -0
  55. package/dungeons/vertical/marketplace.js +844 -0
  56. package/dungeons/vertical/media-schema.json +787 -0
  57. package/dungeons/{media.js → vertical/media.js} +94 -16
  58. package/dungeons/vertical/rpg-schema.json +654 -0
  59. package/dungeons/{rpg.js → vertical/rpg.js} +78 -57
  60. package/dungeons/vertical/sass-schema.json +653 -0
  61. package/dungeons/{sass.js → vertical/sass.js} +49 -23
  62. package/dungeons/vertical/social-schema.json +552 -0
  63. package/dungeons/{social.js → vertical/social.js} +60 -14
  64. package/dungeons/vertical/travel-schema.json +558 -0
  65. package/dungeons/vertical/travel.js +736 -0
  66. package/index.js +19 -15
  67. package/lib/core/config-validator.js +286 -1
  68. package/lib/core/context.js +7 -5
  69. package/lib/generators/adspend.js +3 -3
  70. package/lib/generators/events.js +141 -14
  71. package/lib/generators/funnels.js +67 -7
  72. package/lib/generators/text.js +2 -2
  73. package/lib/orchestrators/user-loop.js +441 -22
  74. package/lib/templates/soup-presets.js +2 -2
  75. package/lib/utils/utils.js +4 -5
  76. package/package.json +4 -3
  77. package/scripts/dungeon-to-json.mjs +163 -0
  78. package/scripts/extract-dungeon-schema.mjs +297 -0
  79. package/scripts/json-to-dungeon.mjs +200 -0
  80. package/scripts/run-dungeon.mjs +76 -0
  81. package/scripts/run-many.mjs +118 -0
  82. package/scripts/verify-runner.mjs +42 -0
  83. package/types.d.ts +313 -1
  84. package/dungeons/array-of-object-lookup-schema.json +0 -327
  85. package/dungeons/ecommerce-schema.json +0 -462
  86. package/dungeons/education-schema.json +0 -2409
  87. package/dungeons/fintech-schema.json +0 -14034
  88. package/dungeons/foobar-schema.json +0 -403
  89. package/dungeons/food-delivery-schema.json +0 -192
  90. package/dungeons/food-delivery.js +0 -602
  91. package/dungeons/food-schema.json +0 -1152
  92. package/dungeons/gaming-schema.json +0 -1270
  93. package/dungeons/insurance-application-schema.json +0 -204
  94. package/dungeons/media-schema.json +0 -906
  95. package/dungeons/retention-cadence-schema.json +0 -78
  96. package/dungeons/rpg-schema.json +0 -4526
  97. package/dungeons/sanity-schema.json +0 -255
  98. package/dungeons/sass-schema.json +0 -1291
  99. package/dungeons/scd-schema.json +0 -919
  100. package/dungeons/simple-schema.json +0 -608
  101. package/dungeons/simplest-schema.json +0 -1418
  102. package/dungeons/social-schema.json +0 -1118
  103. 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 "../lib/utils/utils.js";
4
+ import * as u from "../../lib/utils/utils.js";
5
5
  import * as v from "ak-tools";
6
6
 
7
7
  const SEED = "harness-food";
@@ -194,7 +194,7 @@ const config = {
194
194
  conversionRate: 55,
195
195
  timeToConvert: 1,
196
196
  weight: 5,
197
- props: { "restaurant_id": u.pickAWinner(restaurantIds) },
197
+ props: { "restaurant_id": restaurantIds },
198
198
  },
199
199
  {
200
200
  // Search-driven ordering
@@ -209,7 +209,7 @@ const config = {
209
209
  conversionRate: 65,
210
210
  timeToConvert: 2,
211
211
  weight: 4,
212
- props: { "order_id": u.pickAWinner(orderIds) },
212
+ props: { "order_id": orderIds },
213
213
  },
214
214
  {
215
215
  // Post-order: rate and reorder
@@ -248,7 +248,8 @@ const config = {
248
248
  isFirstEvent: true,
249
249
  properties: {
250
250
  "signup_method": ["email", "google", "apple", "facebook"],
251
- "referral_code": u.pickAWinner([true, false], 0.3),
251
+ "referral_code": [false, false, true],
252
+ "trial_retained": [false],
252
253
  }
253
254
  },
254
255
  {
@@ -266,14 +267,15 @@ const config = {
266
267
  "Mediterranean"
267
268
  ],
268
269
  "sort_by": ["recommended", "distance", "rating", "price"],
269
- "filter_applied": u.pickAWinner([true, false], 0.4),
270
+ "filter_applied": [false, false, false, true, true],
271
+ "trial_retained": [false],
270
272
  }
271
273
  },
272
274
  {
273
275
  event: "restaurant viewed",
274
276
  weight: 15,
275
277
  properties: {
276
- "restaurant_id": u.pickAWinner(restaurantIds),
278
+ "restaurant_id": restaurantIds,
277
279
  "cuisine_type": [
278
280
  "American",
279
281
  "Italian",
@@ -287,33 +289,40 @@ const config = {
287
289
  "avg_rating": u.weighNumRange(1, 5, 0.8, 30),
288
290
  "delivery_time_est_mins": u.weighNumRange(15, 90, 1.2, 40),
289
291
  "price_tier": ["$", "$$", "$$$", "$$$$"],
292
+ "late_night_order": [false],
293
+ "trial_retained": [false],
290
294
  }
291
295
  },
292
296
  {
293
297
  event: "item added to cart",
294
298
  weight: 14,
295
299
  properties: {
296
- "item_id": u.pickAWinner(itemIds),
300
+ "item_id": itemIds,
297
301
  "item_category": ["entree", "appetizer", "drink", "dessert", "side"],
298
302
  "item_price": u.weighNumRange(3, 65, 1.0, 40),
299
303
  "customization_count": u.weighNumRange(0, 5, 1.5, 20),
304
+ "late_night_order": [false],
305
+ "trial_retained": [false],
300
306
  }
301
307
  },
302
308
  {
303
309
  event: "item removed from cart",
304
310
  weight: 5,
305
311
  properties: {
306
- "item_id": u.pickAWinner(itemIds),
312
+ "item_id": itemIds,
307
313
  "removal_reason": ["changed_mind", "too_expensive", "substitution"],
314
+ "trial_retained": [false],
308
315
  }
309
316
  },
310
317
  {
311
318
  event: "coupon applied",
312
319
  weight: 4,
313
320
  properties: {
314
- "coupon_code": u.pickAWinner(couponCodes),
321
+ "coupon_code": couponCodes,
315
322
  "discount_type": ["percent", "flat", "free_delivery"],
316
323
  "discount_value": u.weighNumRange(5, 50, 1.2, 20),
324
+ "coupon_injected": [false],
325
+ "trial_retained": [false],
317
326
  }
318
327
  },
319
328
  {
@@ -322,46 +331,54 @@ const config = {
322
331
  properties: {
323
332
  "cart_total": u.weighNumRange(8, 150, 0.8, 40),
324
333
  "items_count": u.weighNumRange(1, 8, 1.2, 20),
325
- "delivery_address_saved": u.pickAWinner([true, false], 0.7),
334
+ "delivery_address_saved": [false, false, false, true, true, true, true, true, true, true],
335
+ "trial_retained": [false],
326
336
  }
327
337
  },
328
338
  {
329
339
  event: "order placed",
330
340
  weight: 10,
331
341
  properties: {
332
- "order_id": u.pickAWinner(orderIds),
342
+ "order_id": orderIds,
333
343
  "payment_method": ["credit_card", "apple_pay", "google_pay", "paypal", "cash"],
334
344
  "order_total": u.weighNumRange(10, 200, 0.8, 40),
335
345
  "tip_amount": u.weighNumRange(0, 30, 1.5, 20),
336
346
  "delivery_fee": u.weighNumRange(0, 12, 1.0, 20),
347
+ "surge_pricing": [false],
348
+ "rainy_week": [false],
349
+ "trial_retained": [false],
337
350
  }
338
351
  },
339
352
  {
340
353
  event: "order tracked",
341
354
  weight: 13,
342
355
  properties: {
343
- "order_id": u.pickAWinner(orderIds),
356
+ "order_id": orderIds,
344
357
  "order_status": ["confirmed", "preparing", "picked_up", "en_route", "delivered"],
345
358
  "eta_mins": u.weighNumRange(5, 60, 1.0, 30),
359
+ "trial_retained": [false],
346
360
  }
347
361
  },
348
362
  {
349
363
  event: "order delivered",
350
364
  weight: 9,
351
365
  properties: {
352
- "order_id": u.pickAWinner(orderIds),
366
+ "order_id": orderIds,
353
367
  "actual_delivery_mins": u.weighNumRange(12, 90, 1.0, 40),
354
- "on_time": u.pickAWinner([true, false], 0.7),
368
+ "on_time": [false, false, false, true, true, true, true, true, true, true],
369
+ "trial_retained": [false],
355
370
  }
356
371
  },
357
372
  {
358
373
  event: "order rated",
359
374
  weight: 7,
360
375
  properties: {
361
- "order_id": u.pickAWinner(orderIds),
376
+ "order_id": orderIds,
362
377
  "food_rating": u.weighNumRange(1, 5, 0.8, 30),
363
378
  "delivery_rating": u.weighNumRange(1, 5, 0.8, 30),
364
- "would_reorder": u.pickAWinner([true, false], 0.65),
379
+ "would_reorder": [false, true, true],
380
+ "referral_user": [false],
381
+ "trial_retained": [false],
365
382
  }
366
383
  },
367
384
  {
@@ -375,6 +392,7 @@ const config = {
375
392
  ]),
376
393
  "results_count": u.weighNumRange(0, 50, 0.8, 30),
377
394
  "search_type": ["restaurant", "cuisine", "dish"],
395
+ "trial_retained": [false],
378
396
  }
379
397
  },
380
398
  {
@@ -384,15 +402,17 @@ const config = {
384
402
  "promo_id": () => `promo_${v.uid(5)}`,
385
403
  "promo_type": ["banner", "push", "in_feed"],
386
404
  "promo_value": ["10%", "15%", "20%", "25%", "30%", "40%", "50%"],
405
+ "trial_retained": [false],
387
406
  }
388
407
  },
389
408
  {
390
409
  event: "subscription started",
391
410
  weight: 2,
392
411
  properties: {
393
- "plan": u.pickAWinner(["quickbite_plus_monthly", "quickbite_plus_monthly", "quickbite_plus_annual"]),
394
- "price": u.pickAWinner([9.99, 9.99, 79.99]),
395
- "trial": u.pickAWinner([true, false], 0.5),
412
+ "plan": ["quickbite_plus_monthly", "quickbite_plus_monthly", "quickbite_plus_annual"],
413
+ "price": [9.99, 9.99, 79.99],
414
+ "trial": [true, false],
415
+ "trial_retained": [false],
396
416
  }
397
417
  },
398
418
  {
@@ -401,6 +421,7 @@ const config = {
401
421
  properties: {
402
422
  "reason": ["too_expensive", "not_ordering_enough", "found_alternative", "bad_experience"],
403
423
  "months_subscribed": u.weighNumRange(1, 24, 1.5, 15),
424
+ "trial_retained": [false],
404
425
  }
405
426
  },
406
427
  {
@@ -408,22 +429,25 @@ const config = {
408
429
  weight: 3,
409
430
  properties: {
410
431
  "issue_type": ["missing_item", "wrong_order", "late_delivery", "quality_issue", "refund_request"],
411
- "order_id": u.pickAWinner(orderIds),
432
+ "order_id": orderIds,
433
+ "trial_retained": [false],
412
434
  }
413
435
  },
414
436
  {
415
437
  event: "reorder initiated",
416
438
  weight: 6,
417
439
  properties: {
418
- "order_id": u.pickAWinner(orderIds),
440
+ "order_id": orderIds,
419
441
  "original_order_age_days": u.weighNumRange(1, 60, 1.5, 30),
442
+ "referral_user": [false],
443
+ "trial_retained": [false],
420
444
  }
421
445
  },
422
446
  ],
423
447
 
424
448
  superProps: {
425
449
  platform: ["iOS", "Android", "Web"],
426
- subscription_tier: u.pickAWinner(["Free", "Free", "Free", "Free", "QuickBite+"]),
450
+ subscription_tier: ["Free", "Free", "Free", "Free", "QuickBite+"],
427
451
  city: ["New York", "Los Angeles", "Chicago", "Houston", "Phoenix", "San Francisco"],
428
452
  },
429
453
 
@@ -441,6 +465,8 @@ const config = {
441
465
  "avg_order_value": u.weighNumRange(15, 80, 0.8, 40),
442
466
  "orders_per_month": u.weighNumRange(1, 20, 1.5, 10),
443
467
  "favorite_restaurant_count": u.weighNumRange(1, 10),
468
+ "is_high_risk": [false],
469
+ "churn_risk_score": [0],
444
470
  },
445
471
 
446
472
  groupKeys: [
@@ -559,7 +585,9 @@ const config = {
559
585
  'milliseconds'
560
586
  ).toISOString();
561
587
 
588
+ const couponTemplate = record.find(e => e.event === "coupon applied");
562
589
  const couponEvent = {
590
+ ...(couponTemplate || firstEvent),
563
591
  event: "coupon applied",
564
592
  time: midTime,
565
593
  user_id: firstEvent.user_id,
@@ -670,7 +698,7 @@ const config = {
670
698
  if (isReferralUser && event.event === "reorder initiated" && chance.bool({ likelihood: 50 })) {
671
699
  const eventTime = dayjs(event.time);
672
700
  const extraReorder = {
673
- event: "reorder initiated",
701
+ ...event,
674
702
  time: eventTime.add(chance.integer({ min: 1, max: 7 }), 'days').toISOString(),
675
703
  user_id: event.user_id,
676
704
  order_id: chance.pickone(orderIds),
@@ -0,0 +1,394 @@
1
+ {
2
+ "events": [
3
+ {
4
+ "event": "app install",
5
+ "weight": 10,
6
+ "isFirstEvent": true
7
+ },
8
+ {
9
+ "event": "character creation",
10
+ "weight": 2,
11
+ "properties": {
12
+ "mode": [
13
+ "fast",
14
+ "slow",
15
+ "template"
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "event": "join party",
21
+ "weight": 8,
22
+ "properties": {
23
+ "party size": {
24
+ "$range": [
25
+ 2,
26
+ 5
27
+ ]
28
+ },
29
+ "party leader": [
30
+ "Bard",
31
+ "Cleric",
32
+ "Fighter",
33
+ "Rogue",
34
+ "Wizard",
35
+ "Paladin",
36
+ "Ranger",
37
+ "Sorcerer",
38
+ "Warlock"
39
+ ]
40
+ }
41
+ },
42
+ {
43
+ "event": "start quest",
44
+ "weight": 12,
45
+ "properties": {
46
+ "quest type": [
47
+ "Rescue",
48
+ "Retrieve",
49
+ "Explore",
50
+ "Destroy",
51
+ "Investigate"
52
+ ],
53
+ "quest difficulty": [
54
+ "Easy",
55
+ "Medium",
56
+ "Hard",
57
+ "Legendary"
58
+ ],
59
+ "quest location": [
60
+ "Forest",
61
+ "Dungeon",
62
+ "Mountain",
63
+ "City",
64
+ "Desert"
65
+ ],
66
+ "party size": {
67
+ "$range": [
68
+ 2,
69
+ 5
70
+ ]
71
+ },
72
+ "used hint": {
73
+ "$type": "array"
74
+ },
75
+ "used boost": {
76
+ "$type": "array"
77
+ },
78
+ "level at start": {
79
+ "$range": [
80
+ 2,
81
+ 17
82
+ ]
83
+ }
84
+ }
85
+ },
86
+ {
87
+ "event": "complete quest",
88
+ "weight": 12,
89
+ "properties": {
90
+ "completion time (mins)": {
91
+ "$range": [
92
+ 20,
93
+ 115
94
+ ]
95
+ },
96
+ "quest reward (gold)": {
97
+ "$range": [
98
+ 11,
99
+ 451
100
+ ]
101
+ },
102
+ "quest success": {
103
+ "$type": "array"
104
+ },
105
+ "used hint": {
106
+ "$type": "array"
107
+ },
108
+ "used boost": {
109
+ "$type": "array"
110
+ },
111
+ "number of deaths": [
112
+ 1,
113
+ 3
114
+ ],
115
+ "level at start": {
116
+ "$range": [
117
+ 2,
118
+ 19
119
+ ]
120
+ },
121
+ "level at end": {
122
+ "$range": [
123
+ 2,
124
+ 19
125
+ ]
126
+ }
127
+ }
128
+ },
129
+ {
130
+ "event": "gameplay summary",
131
+ "weight": 14,
132
+ "properties": {
133
+ "# enemies defeated": {
134
+ "$range": [
135
+ 7,
136
+ 93
137
+ ]
138
+ },
139
+ "# respawns": {
140
+ "$range": [
141
+ 0,
142
+ 10
143
+ ]
144
+ },
145
+ "# attacks": {
146
+ "$range": [
147
+ 14,
148
+ 52
149
+ ]
150
+ },
151
+ "# gold found": {
152
+ "$range": [
153
+ 49,
154
+ 886
155
+ ]
156
+ }
157
+ }
158
+ },
159
+ {
160
+ "event": "in-game purchase",
161
+ "weight": 2,
162
+ "properties": {
163
+ "purchase type": [
164
+ "Gold",
165
+ "Gems",
166
+ "Items: Weapons",
167
+ "Items: Armor",
168
+ "Items: Potions",
169
+ "Items: Scrolls",
170
+ "Boosts",
171
+ "Currency"
172
+ ],
173
+ "purchase amount": {
174
+ "$range": [
175
+ 3,
176
+ 36
177
+ ]
178
+ },
179
+ "is_whale": [
180
+ false
181
+ ]
182
+ }
183
+ },
184
+ {
185
+ "event": "fight boss",
186
+ "weight": 3,
187
+ "properties": {
188
+ "boss type": [
189
+ "Dragon",
190
+ "Demon",
191
+ "Lich",
192
+ "Vampire",
193
+ "Beholder"
194
+ ],
195
+ "boss level": {
196
+ "$range": [
197
+ 10,
198
+ 18
199
+ ]
200
+ },
201
+ "boss difficulty": [
202
+ "Hard",
203
+ "Legendary",
204
+ "Impossible"
205
+ ],
206
+ "fight duration (mins)": {
207
+ "$range": [
208
+ 6,
209
+ 59
210
+ ]
211
+ }
212
+ }
213
+ },
214
+ {
215
+ "event": "level up",
216
+ "properties": {
217
+ "new abilities": [
218
+ "Attack",
219
+ "Spell",
220
+ "Feat",
221
+ "Skill"
222
+ ]
223
+ }
224
+ },
225
+ {
226
+ "event": "attack",
227
+ "weight": 5,
228
+ "properties": {
229
+ "generic_prop": [
230
+ "foo",
231
+ "bar",
232
+ "baz",
233
+ "qux"
234
+ ]
235
+ }
236
+ },
237
+ {
238
+ "event": "defend",
239
+ "weight": 3,
240
+ "properties": {
241
+ "generic_prop": [
242
+ "foo",
243
+ "bar",
244
+ "baz",
245
+ "qux"
246
+ ]
247
+ }
248
+ }
249
+ ],
250
+ "superProps": {
251
+ "platform": [
252
+ "Mobile",
253
+ "Xbox",
254
+ "Playstation",
255
+ "Switch",
256
+ "Web"
257
+ ],
258
+ "game mode": [
259
+ "Single Player",
260
+ "Multiplayer"
261
+ ],
262
+ "language": [
263
+ "English",
264
+ "Spanish",
265
+ "French",
266
+ "German",
267
+ "Japanese",
268
+ "Korean",
269
+ "Chinese"
270
+ ]
271
+ },
272
+ "userProps": {
273
+ "experiment": [
274
+ "fast leveling",
275
+ "tension economy",
276
+ "free trial"
277
+ ],
278
+ "variant": [
279
+ "A",
280
+ "B",
281
+ "C",
282
+ "Control"
283
+ ],
284
+ "race": [
285
+ "Human",
286
+ "Elf",
287
+ "Dwarf",
288
+ "Halfling",
289
+ "Dragonborn",
290
+ "Gnome",
291
+ "Half-Elf",
292
+ "Half-Orc",
293
+ "Tiefling"
294
+ ],
295
+ "class": [
296
+ "Barbarian",
297
+ "Bard",
298
+ "Cleric",
299
+ "Druid",
300
+ "Fighter",
301
+ "Monk",
302
+ "Paladin",
303
+ "Ranger",
304
+ "Rogue",
305
+ "Sorcerer",
306
+ "Warlock",
307
+ "Wizard"
308
+ ],
309
+ "alignment": [
310
+ "Lawful Good",
311
+ "Neutral Good",
312
+ "Chaotic Good",
313
+ "Lawful Neutral",
314
+ "True Neutral",
315
+ "Chaotic Neutral",
316
+ "Lawful Evil",
317
+ "Neutral Evil",
318
+ "Chaotic Evil"
319
+ ],
320
+ "level": {
321
+ "$range": [
322
+ 2,
323
+ 17
324
+ ]
325
+ },
326
+ "background": [
327
+ "Acolyte",
328
+ "Charlatan",
329
+ "Criminal",
330
+ "Entertainer",
331
+ "Folk Hero",
332
+ "Guild Artisan",
333
+ "Hermit",
334
+ "Noble",
335
+ "Outlander",
336
+ "Sage",
337
+ "Sailor",
338
+ "Soldier",
339
+ "Urchin"
340
+ ],
341
+ "subscription MRR": {
342
+ "$range": [
343
+ 1,
344
+ 221
345
+ ]
346
+ },
347
+ "archetype": [
348
+ "neutral"
349
+ ]
350
+ },
351
+ "funnels": [
352
+ {
353
+ "sequence": [
354
+ "app install",
355
+ "character creation",
356
+ "join party"
357
+ ],
358
+ "isFirstFunnel": true,
359
+ "conversionRate": 0.8,
360
+ "timeToConvert": 0.25
361
+ },
362
+ {
363
+ "sequence": [
364
+ "start quest",
365
+ "gameplay summary",
366
+ "complete quest"
367
+ ],
368
+ "conversionRate": 0.99,
369
+ "timeToConvert": 1,
370
+ "props": {
371
+ "quest type": [
372
+ "Rescue",
373
+ "Retrieve",
374
+ "Explore",
375
+ "Destroy",
376
+ "Investigate"
377
+ ],
378
+ "quest difficulty": [
379
+ "Easy",
380
+ "Medium",
381
+ "Hard",
382
+ "Legendary"
383
+ ],
384
+ "quest location": [
385
+ "Forest",
386
+ "Dungeon",
387
+ "Mountain",
388
+ "City",
389
+ "Desert"
390
+ ]
391
+ }
392
+ }
393
+ ]
394
+ }
@@ -2,7 +2,7 @@
2
2
  import dayjs from "dayjs";
3
3
  import utc from "dayjs/plugin/utc.js";
4
4
  import "dotenv/config";
5
- import * as u from "../lib/utils/utils.js";
5
+ import * as u from "../../lib/utils/utils.js";
6
6
  import * as v from "ak-tools";
7
7
 
8
8
  const SEED = "my-seed";
@@ -265,8 +265,8 @@ const config = {
265
265
  "Desert",
266
266
  ],
267
267
  "party size": u.weighNumRange(1, 6),
268
- "used hint": u.pickAWinner(["yes", "no"], 0.3),
269
- "used boost": u.pickAWinner(["yes", "no"], 0.2),
268
+ "used hint": ["no", "no", "yes"],
269
+ "used boost": ["no", "no", "no", "no", "yes"],
270
270
  "level at start": u.weighNumRange(1, 20),
271
271
  },
272
272
  },
@@ -276,9 +276,9 @@ const config = {
276
276
  properties: {
277
277
  "completion time (mins)": u.weighNumRange(5, 120, 1, 30),
278
278
  "quest reward (gold)": u.weighNumRange(10, 500, 1, 100),
279
- "quest success": u.pickAWinner(["yes", "no"], 0.9),
280
- "used hint": u.pickAWinner(["yes", "no"], 0.3),
281
- "used boost": u.pickAWinner(["yes", "no"], 0.2),
279
+ "quest success": ["yes", "yes", "yes", "yes", "yes", "yes", "yes", "yes", "yes", "no"],
280
+ "used hint": ["no", "no", "yes"],
281
+ "used boost": ["no", "no", "no", "no", "yes"],
282
282
  "number of deaths": u.weighNumRange(0, 5, 1, 2),
283
283
  "level at start": u.weighNumRange(1, 20),
284
284
  "level at end": u.weighNumRange(1, 20),
@@ -309,6 +309,7 @@ const config = {
309
309
  "Currency",
310
310
  ],
311
311
  "purchase amount": u.weighNumRange(1, 50, 1, 20),
312
+ is_whale: [false],
312
313
  }
313
314
  },
314
315
  {
@@ -451,7 +452,8 @@ const config = {
451
452
  "Soldier",
452
453
  "Urchin",
453
454
  ],
454
- "subscription MRR": u.weighNumRange(0, 250, 1, 200)
455
+ "subscription MRR": u.weighNumRange(0, 250, 1, 200),
456
+ archetype: ["neutral"],
455
457
  },
456
458
  // HOOK: 3 patterns — gold scaling by level, whale purchases, alignment archetype
457
459
  hook: function (record, type, meta) {