make-mp-data 2.1.6 → 3.0.1

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 (76) hide show
  1. package/README.md +31 -0
  2. package/dungeons/adspend.js +2 -2
  3. package/dungeons/ai-chat-analytics-ed.js +3 -2
  4. package/dungeons/anon.js +2 -2
  5. package/dungeons/array-of-object-loopup.js +181 -0
  6. package/dungeons/benchmark-heavy.js +241 -0
  7. package/dungeons/benchmark-light.js +141 -0
  8. package/dungeons/big.js +9 -8
  9. package/dungeons/business.js +2 -1
  10. package/dungeons/clinch-agi.js +632 -0
  11. package/dungeons/complex.js +3 -2
  12. package/dungeons/copilot.js +383 -0
  13. package/dungeons/ecommerce-store.js +0 -0
  14. package/dungeons/experiments.js +5 -4
  15. package/dungeons/foobar.js +101 -101
  16. package/dungeons/funnels.js +2 -2
  17. package/dungeons/gaming.js +3 -2
  18. package/dungeons/harness/harness-education.js +988 -0
  19. package/dungeons/harness/harness-fintech.js +976 -0
  20. package/dungeons/harness/harness-food.js +985 -0
  21. package/dungeons/harness/harness-gaming.js +1178 -0
  22. package/dungeons/harness/harness-media.js +961 -0
  23. package/dungeons/harness/harness-sass.js +923 -0
  24. package/dungeons/harness/harness-social.js +928 -0
  25. package/dungeons/kurby.js +211 -0
  26. package/dungeons/media.js +5 -4
  27. package/dungeons/mil.js +4 -3
  28. package/dungeons/mirror.js +2 -2
  29. package/dungeons/money2020-ed.js +8 -7
  30. package/dungeons/sanity.js +3 -2
  31. package/dungeons/scd.js +3 -2
  32. package/dungeons/simple.js +29 -14
  33. package/dungeons/strict-event-test.js +30 -0
  34. package/dungeons/student-teacher.js +3 -2
  35. package/dungeons/text-generation.js +84 -85
  36. package/dungeons/too-big-events.js +166 -0
  37. package/dungeons/uday-schema.json +220 -0
  38. package/dungeons/userAgent.js +4 -3
  39. package/index.js +41 -54
  40. package/lib/core/config-validator.js +122 -7
  41. package/lib/core/context.js +7 -14
  42. package/lib/core/storage.js +60 -30
  43. package/lib/generators/adspend.js +12 -27
  44. package/lib/generators/events.js +6 -7
  45. package/lib/generators/funnels.js +16 -5
  46. package/lib/generators/product-lookup.js +262 -0
  47. package/lib/generators/product-names.js +195 -0
  48. package/lib/generators/profiles.js +3 -3
  49. package/lib/generators/scd.js +13 -3
  50. package/lib/generators/text.js +17 -4
  51. package/lib/orchestrators/mixpanel-sender.js +251 -208
  52. package/lib/orchestrators/user-loop.js +57 -19
  53. package/lib/templates/funnels-instructions.txt +272 -0
  54. package/lib/templates/hook-examples.json +187 -0
  55. package/lib/templates/hooks-instructions.txt +295 -8
  56. package/lib/templates/phrases.js +473 -16
  57. package/lib/templates/refine-instructions.txt +485 -0
  58. package/lib/templates/schema-instructions.txt +239 -109
  59. package/lib/templates/schema.d.ts +173 -0
  60. package/lib/templates/verbose-schema.js +140 -206
  61. package/lib/utils/ai.js +853 -77
  62. package/lib/utils/chart.js +210 -0
  63. package/lib/utils/function-registry.js +285 -0
  64. package/lib/utils/json-evaluator.js +172 -0
  65. package/lib/utils/logger.js +38 -0
  66. package/lib/utils/mixpanel.js +101 -0
  67. package/lib/utils/project.js +3 -2
  68. package/lib/utils/utils.js +41 -4
  69. package/package.json +13 -19
  70. package/types.d.ts +15 -5
  71. package/lib/generators/text-bak-old.js +0 -1121
  72. package/lib/orchestrators/worker-manager.js +0 -203
  73. package/lib/templates/phrases-bak.js +0 -925
  74. package/lib/templates/prompt (old).txt +0 -98
  75. package/lib/templates/scratch-dungeon-template.js +0 -116
  76. package/lib/templates/textQuickTest.js +0 -172
@@ -0,0 +1,1178 @@
1
+ import dayjs from "dayjs";
2
+ import utc from "dayjs/plugin/utc.js";
3
+ import "dotenv/config";
4
+ import * as u from "../../lib/utils/utils.js";
5
+ import * as v from "ak-tools";
6
+
7
+ const SEED = "harness-gaming";
8
+ dayjs.extend(utc);
9
+ const chance = u.initChance(SEED);
10
+ const num_users = 5_000;
11
+ const days = 100;
12
+
13
+ /** @typedef {import("../../types.js").Dungeon} Config */
14
+
15
+ /**
16
+ * 🎮 NEEDLE IN A HAYSTACK - GAME DESIGN
17
+ *
18
+ * A D&D-style action RPG with deep strategic gameplay and a robust player-driven economy.
19
+ *
20
+ * CORE GAMEPLAY LOOP:
21
+ * Players create characters (Warrior, Mage, Rogue, etc.) and embark on epic adventures through
22
+ * a vast fantasy world. The game emphasizes strategic preparation, guild cooperation, and
23
+ * risk/reward decision-making. Success requires both skill and planning.
24
+ *
25
+ * QUEST SYSTEM (events: quest accepted → objective completed → turned in):
26
+ * - Five quest types: Main Story (narrative progression), Side Quests (world-building),
27
+ * Bounties (repeatable challenges), Exploration (discovery rewards), Escorts (protect NPCs)
28
+ * - Quest difficulty scaling based on player level
29
+ * - Rewards include gold (in-game economy), XP (progression), and rare items
30
+ * - Players can accept multiple quests and complete them in any order
31
+ *
32
+ * DUNGEON EXPLORATION (events: enter → find treasure → exit):
33
+ * - 50 unique dungeons with varying difficulty (Easy → Deadly)
34
+ * - Party-based gameplay: solo or group (1-5 players coordinated through guilds)
35
+ * - Treasure hunting: gold, weapons, armor, consumables, and legendary artifacts
36
+ * - Three outcomes: completed (reached the end), abandoned (left early), died (party wipe)
37
+ * - Time investment: 5-120 minutes per run
38
+ *
39
+ * STRATEGIC PREPARATION (events: inspect, search for clues):
40
+ * - "Inspect" lets players scout enemies, traps, and treasure before committing
41
+ * - "Search for clues" reveals hidden paths, secret rewards, and dungeon mechanics
42
+ * - Players who prepare strategically have significantly better outcomes
43
+ * - The Ancient Compass is a rare consumable that enhances exploration success
44
+ *
45
+ * COMBAT SYSTEM (events: combat initiated → combat completed):
46
+ * - Real-time combat against 6 enemy types: Goblins (swarms), Skeletons (undead),
47
+ * Dragons (bosses), Demons (elite), Undead (cursed), Beasts (wilderness)
48
+ * - Level-based difficulty: enemies scale from 1-50
49
+ * - Three outcomes: Victory (loot), Defeat (death), Fled (escaped but no rewards)
50
+ * - Combat duration reflects difficulty (10s quick fights → 300s epic battles)
51
+ *
52
+ * DEATH & RESURRECTION (event: player death):
53
+ * - Players can die from monsters, traps, fall damage, poison, or friendly fire
54
+ * - Death penalties: lost time, equipment durability loss, potential item drops
55
+ * - Resurrection Stones (consumable) allow instant revival without penalties
56
+ * - Deaths early in a player's journey often lead to frustration and churn
57
+ *
58
+ * CHARACTER PROGRESSION (events: level up):
59
+ * - 50 levels of progression (1-50)
60
+ * - Each level grants stat points to customize character builds
61
+ * - Six classes with unique playstyles and abilities
62
+ * - Five races with lore and starting bonuses
63
+ *
64
+ * ECONOMY SYSTEMS:
65
+ * - In-game gold economy: earn through quests/dungeons, spend at vendors
66
+ * - Item trading: buy/sell weapons, armor, potions, scrolls (events: item purchased/sold)
67
+ * - Vendor types: Town (general goods), Dungeon (mid-adventure resupply), Special Events (rare items)
68
+ * - Item rarity: Common → Uncommon → Rare → Epic → Legendary (affects pricing)
69
+ *
70
+ * MONETIZATION (event: real money purchase):
71
+ * - Free-to-play with optional purchases
72
+ * - Premium currency (1000/5000 gems) for cosmetics and convenience
73
+ * - Lucky Charm Pack: increases rare drop rates (creates high-LTV player segment)
74
+ * - Legendary Weapon Chests: random powerful gear
75
+ * - Season Pass: exclusive content, cosmetics, and progression boosts
76
+ * - Cosmetic Bundles: no gameplay impact, pure customization
77
+ *
78
+ * GUILD SYSTEM (events: guild joined/left):
79
+ * - Social cooperative play through guilds (5-100 members)
80
+ * - Guild levels (1-20) unlock perks and group content
81
+ * - Shared progression and coordinated dungeon runs
82
+ * - Early guild joining creates social bonds that dramatically improve retention
83
+ * - Reasons for leaving: Inactive guilds, found better fit, conflicts, guild disbanded
84
+ *
85
+ * ITEM USAGE (event: use item):
86
+ * - Consumables: Health/Mana Potions (combat sustainability), Buff Scrolls (temporary power)
87
+ * - Strategic items: Ancient Compass (exploration aid), Lucky Charm (drop rate boost)
88
+ * - Combat items: Resurrection Stone (death prevention)
89
+ * - Context matters: Combat, Exploration, Boss Fights, or Casual use
90
+ *
91
+ * SUBSCRIPTION TIERS (SCD: subscription_tier):
92
+ * - Free: Base game access, earn everything through play
93
+ * - Premium ($9.99/mo): Faster progression, extra inventory, priority queues
94
+ * - Elite ($19.99/mo): All Premium benefits + exclusive content, monthly gems
95
+ * - Tiers can change monthly based on player engagement and value perception
96
+ *
97
+ * WHY THESE EVENTS/PROPERTIES?
98
+ * - Events model a complete game loop: onboarding → engagement → monetization → retention
99
+ * - Properties enable cohort analysis: class/race choices, difficulty preferences, spending patterns
100
+ * - Funnels reveal friction: where do players drop off in onboarding, quests, dungeons?
101
+ * - Strategic depth (inspect, search, compass) creates skill gaps visible in the data
102
+ * - Social features (guilds) and monetization (purchases) drive business metrics
103
+ * - The "needle in haystack" hooks simulate real product insights hidden in production data
104
+ */
105
+
106
+ // Generate consistent item/location IDs for lookup tables
107
+ const dungeonIds = v.range(1, 51).map(n => `dungeon_${v.uid(6)}`);
108
+ const questIds = v.range(1, 201).map(n => `quest_${v.uid(8)}`);
109
+ const itemIds = v.range(1, 301).map(n => `item_${v.uid(7)}`);
110
+
111
+ /** @type {Config} */
112
+ const config = {
113
+ token: "7958c5407b34dbbeef4db2c9d1f032d4",
114
+ seed: SEED,
115
+ numDays: days,
116
+ numEvents: num_users * 120,
117
+ numUsers: num_users,
118
+ hasAnonIds: false,
119
+ hasSessionIds: true,
120
+ format: "json",
121
+ gzip: true,
122
+ alsoInferFunnels: false,
123
+ hasLocation: true,
124
+ hasAndroidDevices: true,
125
+ hasIOSDevices: true,
126
+ hasDesktopDevices: true,
127
+ hasBrowser: false,
128
+ hasCampaigns: false,
129
+ isAnonymous: false,
130
+ hasAdSpend: false,
131
+ percentUsersBornInDataset: 50,
132
+
133
+ hasAvatar: true,
134
+ makeChart: false,
135
+
136
+ batchSize: 2_500_000,
137
+ concurrency: 10,
138
+ writeToDisk: false,
139
+
140
+ funnels: [
141
+ {
142
+ sequence: ["character created", "tutorial completed", "quest accepted"],
143
+ isFirstFunnel: true,
144
+ conversionRate: 75,
145
+ timeToConvert: 0.5,
146
+ },
147
+ {
148
+ // Core combat loop: most frequent player activity
149
+ sequence: ["combat initiated", "combat completed", "use item"],
150
+ conversionRate: 75,
151
+ timeToConvert: 0.5,
152
+ weight: 5,
153
+ },
154
+ {
155
+ // Dungeon crawl: enter, explore, loot, exit
156
+ sequence: ["enter dungeon", "find treasure", "exit dungeon"],
157
+ conversionRate: 60,
158
+ timeToConvert: 2,
159
+ weight: 4,
160
+ props: {
161
+ "dungeon_id": u.pickAWinner(dungeonIds),
162
+ "difficulty": u.pickAWinner(["Easy", "Medium", "Hard", "Deadly"]),
163
+ }
164
+ },
165
+ {
166
+ // Quest lifecycle
167
+ sequence: ["quest accepted", "quest objective completed", "quest turned in"],
168
+ conversionRate: 55,
169
+ timeToConvert: 3,
170
+ weight: 3,
171
+ props: { "quest_id": u.pickAWinner(questIds) },
172
+ },
173
+ {
174
+ // Preparation before dungeon: inspect + search for strategic explorer hook
175
+ sequence: ["inspect", "search for clues", "enter dungeon"],
176
+ conversionRate: 50,
177
+ timeToConvert: 1,
178
+ weight: 3,
179
+ },
180
+ {
181
+ // Economy: buy gear, sell loot
182
+ sequence: ["item purchased", "use item", "item sold"],
183
+ conversionRate: 45,
184
+ timeToConvert: 6,
185
+ weight: 2,
186
+ },
187
+ {
188
+ // Social and progression
189
+ sequence: ["guild joined", "level up", "real money purchase"],
190
+ conversionRate: 25,
191
+ timeToConvert: 24,
192
+ weight: 1,
193
+ },
194
+ ],
195
+
196
+ events: [
197
+ {
198
+ event: "character created",
199
+ weight: 1,
200
+ isFirstEvent: true,
201
+ properties: {
202
+ "character_class": u.pickAWinner([
203
+ "Warrior",
204
+ "Mage",
205
+ "Rogue",
206
+ "Cleric",
207
+ "Ranger",
208
+ "Paladin"
209
+ ]),
210
+ "starting_race": u.pickAWinner([
211
+ "Human",
212
+ "Elf",
213
+ "Dwarf",
214
+ "Halfling",
215
+ "Orc"
216
+ ]),
217
+ }
218
+ },
219
+ {
220
+ event: "tutorial completed",
221
+ weight: 2,
222
+ properties: {
223
+ "completion_time_mins": u.weighNumRange(3, 25, 0.8, 10),
224
+ "skipped": u.pickAWinner([true, false], 0.15),
225
+ }
226
+ },
227
+ {
228
+ event: "quest accepted",
229
+ weight: 15,
230
+ properties: {
231
+ "quest_id": u.pickAWinner(questIds),
232
+ "quest_type": u.pickAWinner([
233
+ "Main Story",
234
+ "Side Quest",
235
+ "Bounty",
236
+ "Exploration",
237
+ "Escort"
238
+ ]),
239
+ "recommended_level": u.weighNumRange(1, 50),
240
+ }
241
+ },
242
+ {
243
+ event: "quest objective completed",
244
+ weight: 12,
245
+ properties: {
246
+ "quest_id": u.pickAWinner(questIds),
247
+ "objective_number": u.weighNumRange(1, 5),
248
+ }
249
+ },
250
+ {
251
+ event: "quest turned in",
252
+ weight: 10,
253
+ properties: {
254
+ "quest_id": u.pickAWinner(questIds),
255
+ "reward_gold": u.weighNumRange(10, 500, 0.5, 100),
256
+ "reward_xp": u.weighNumRange(50, 2000, 0.5, 500),
257
+ }
258
+ },
259
+ {
260
+ event: "enter dungeon",
261
+ weight: 18,
262
+ properties: {
263
+ "dungeon_id": u.pickAWinner(dungeonIds),
264
+ "difficulty": u.pickAWinner(["Easy", "Medium", "Hard", "Deadly"]),
265
+ "party_size": u.weighNumRange(1, 5),
266
+ }
267
+ },
268
+ {
269
+ event: "exit dungeon",
270
+ weight: 14,
271
+ properties: {
272
+ "dungeon_id": u.pickAWinner(dungeonIds),
273
+ "time_spent_mins": u.weighNumRange(5, 120, 0.6, 30),
274
+ "completion_status": u.pickAWinner(["completed", "abandoned", "died"]),
275
+ }
276
+ },
277
+ {
278
+ event: "find treasure",
279
+ weight: 16,
280
+ properties: {
281
+ "treasure_type": u.pickAWinner([
282
+ "Gold",
283
+ "Weapon",
284
+ "Armor",
285
+ "Potion",
286
+ "Scroll",
287
+ "Rare Artifact"
288
+ ]),
289
+ "treasure_value": u.weighNumRange(5, 1000, 1.2, 50),
290
+ }
291
+ },
292
+ {
293
+ event: "player death",
294
+ weight: 8,
295
+ properties: {
296
+ "cause_of_death": u.pickAWinner([
297
+ "Monster",
298
+ "Trap",
299
+ "Fall Damage",
300
+ "Poison",
301
+ "Friendly Fire"
302
+ ]),
303
+ "player_level": u.weighNumRange(1, 50),
304
+ "resurrection_used": u.pickAWinner([true, false], 0.25),
305
+ }
306
+ },
307
+ {
308
+ event: "level up",
309
+ weight: 5,
310
+ properties: {
311
+ "new_level": u.weighNumRange(2, 50),
312
+ "stat_points_gained": u.weighNumRange(1, 5),
313
+ }
314
+ },
315
+ {
316
+ event: "item purchased",
317
+ weight: 11,
318
+ properties: {
319
+ "item_id": u.pickAWinner(itemIds),
320
+ "item_type": u.pickAWinner([
321
+ "Weapon",
322
+ "Armor",
323
+ "Potion",
324
+ "Scroll",
325
+ "Mount",
326
+ "Cosmetic"
327
+ ]),
328
+ "price_gold": u.weighNumRange(10, 500, 0.8, 100),
329
+ "vendor_type": u.pickAWinner(["Town", "Dungeon", "Special Event"]),
330
+ }
331
+ },
332
+ {
333
+ event: "item sold",
334
+ weight: 7,
335
+ properties: {
336
+ "item_id": u.pickAWinner(itemIds),
337
+ "item_type": u.pickAWinner([
338
+ "Weapon",
339
+ "Armor",
340
+ "Potion",
341
+ "Scroll",
342
+ "Junk"
343
+ ]),
344
+ "sell_price": u.weighNumRange(5, 250, 0.5, 50),
345
+ }
346
+ },
347
+ {
348
+ event: "real money purchase",
349
+ weight: 3,
350
+ properties: {
351
+ "product": u.pickAWinner([
352
+ "Premium Currency (1000)",
353
+ "Premium Currency (5000)",
354
+ "Lucky Charm Pack",
355
+ "Legendary Weapon Chest",
356
+ "Cosmetic Bundle",
357
+ "Season Pass"
358
+ ]),
359
+ "price_usd": u.pickAWinner([4.99, 9.99, 19.99, 49.99, 99.99]),
360
+ "payment_method": u.pickAWinner(["Credit Card", "PayPal", "Apple Pay", "Google Pay"]),
361
+ }
362
+ },
363
+ {
364
+ event: "guild joined",
365
+ weight: 4,
366
+ properties: {
367
+ "guild_size": u.weighNumRange(5, 100),
368
+ "guild_level": u.weighNumRange(1, 20),
369
+ }
370
+ },
371
+ {
372
+ event: "guild left",
373
+ weight: 1,
374
+ properties: {
375
+ "reason": u.pickAWinner([
376
+ "Inactive",
377
+ "Found Better Guild",
378
+ "Conflict",
379
+ "Disbanded"
380
+ ]),
381
+ }
382
+ },
383
+ {
384
+ event: "inspect",
385
+ weight: 9,
386
+ properties: {
387
+ "inspect_target": u.pickAWinner([
388
+ "NPC",
389
+ "Monster",
390
+ "Treasure Chest",
391
+ "Door",
392
+ "Statue",
393
+ "Bookshelf"
394
+ ]),
395
+ }
396
+ },
397
+ {
398
+ event: "search for clues",
399
+ weight: 8,
400
+ properties: {
401
+ "location_type": u.pickAWinner([
402
+ "Dungeon Entrance",
403
+ "Hidden Room",
404
+ "Quest Location",
405
+ "Town Square"
406
+ ]),
407
+ "clue_found": u.pickAWinner([true, false], 0.6),
408
+ }
409
+ },
410
+ {
411
+ event: "use item",
412
+ weight: 14,
413
+ properties: {
414
+ "item_id": u.pickAWinner(itemIds),
415
+ "item_type": u.pickAWinner([
416
+ "Health Potion",
417
+ "Mana Potion",
418
+ "Buff Scroll",
419
+ "Ancient Compass",
420
+ "Lucky Charm",
421
+ "Resurrection Stone"
422
+ ]),
423
+ "context": u.pickAWinner(["Combat", "Exploration", "Boss Fight", "Casual"]),
424
+ }
425
+ },
426
+ {
427
+ event: "combat initiated",
428
+ weight: 20,
429
+ properties: {
430
+ "enemy_type": u.pickAWinner([
431
+ "Goblin",
432
+ "Skeleton",
433
+ "Dragon",
434
+ "Demon",
435
+ "Undead",
436
+ "Beast"
437
+ ]),
438
+ "enemy_level": u.weighNumRange(1, 50),
439
+ "combat_duration_sec": u.weighNumRange(10, 300, 0.7, 60),
440
+ }
441
+ },
442
+ {
443
+ event: "combat completed",
444
+ weight: 18,
445
+ properties: {
446
+ "outcome": u.pickAWinner(["Victory", "Defeat", "Fled"]),
447
+ "loot_gained": u.pickAWinner([true, false], 0.7),
448
+ }
449
+ }
450
+ ],
451
+
452
+ superProps: {
453
+ platform: u.pickAWinner([
454
+ "PC",
455
+ "Mac",
456
+ "PlayStation",
457
+ "Xbox",
458
+ "Switch"
459
+ ]),
460
+ graphics_quality: u.pickAWinner([
461
+ "Low",
462
+ "Medium",
463
+ "High",
464
+ "Ultra"
465
+ ]),
466
+ subscription_tier: u.pickAWinner(["Free", "Free", "Free", "Premium", "Elite"]),
467
+ },
468
+
469
+ scdProps: {},
470
+
471
+ userProps: {
472
+ "preferred_playstyle": u.pickAWinner([
473
+ "Solo Explorer",
474
+ "Group Raider",
475
+ "PvP Fighter",
476
+ "Quest Completionist",
477
+ "Treasure Hunter"
478
+ ]),
479
+ "total_playtime_hours": u.weighNumRange(1, 500, 1.5, 50),
480
+ "achievement_points": u.weighNumRange(0, 5000, 0.8, 500),
481
+ "favorite_class": u.pickAWinner([
482
+ "Warrior",
483
+ "Mage",
484
+ "Rogue",
485
+ "Cleric",
486
+ "Ranger",
487
+ "Paladin"
488
+ ]),
489
+ },
490
+
491
+ groupKeys: [
492
+ ["guild_id", 500, ["guild joined", "guild left", "quest turned in", "combat completed"]],
493
+ ],
494
+
495
+ groupProps: {
496
+ guild_id: {
497
+ "name": () => `${chance.word()} ${chance.pickone(["Knights", "Dragons", "Warriors", "Seekers", "Legends"])}`,
498
+ "member_count": u.weighNumRange(5, 100),
499
+ "guild_level": u.weighNumRange(1, 20),
500
+ "total_wealth": u.weighNumRange(1000, 1000000, 0.5, 50000),
501
+ }
502
+ },
503
+
504
+ lookupTables: [],
505
+
506
+ /**
507
+ * 🎯 ARCHITECTED ANALYTICS HOOKS
508
+ *
509
+ * This hook function creates 8 deliberate patterns in the data:
510
+ *
511
+ * 1. CONVERSION: Ancient Compass users have 3x quest completion rate
512
+ * 2. TIME-BASED: "Cursed Week" (days 40-47) has 5x death rates & low completion
513
+ * 3. RETENTION: Early guild joiners (first 3 days) have 80% 30-day retention vs 20%
514
+ * 4. CHURN: Players with 3+ deaths in first week have 70% churn rate
515
+ * 5. PURCHASE VALUE: Lucky Charm buyers spend 5x more (LTV pattern)
516
+ * 6. BEHAVIORS TOGETHER: inspect + search before dungeon = 85% completion vs 45%
517
+ * 7. TIMED RELEASE: Legendary weapon released day 45, early adopters dominate
518
+ * 8. SUBSCRIPTION TIER: Premium/Elite users have higher engagement and success rates
519
+ */
520
+ hook: function (record, type, meta) {
521
+ const NOW = dayjs();
522
+ const DATASET_START = NOW.subtract(days, 'days');
523
+ const CURSED_WEEK_START = DATASET_START.add(40, 'days');
524
+ const CURSED_WEEK_END = DATASET_START.add(47, 'days');
525
+ const LEGENDARY_WEAPON_RELEASE = DATASET_START.add(45, 'days');
526
+
527
+ // Hook #2: TIME-BASED TREND - Cursed Week
528
+ if (type === "event") {
529
+ const EVENT_TIME = dayjs(record.time);
530
+
531
+ // During cursed week, dramatically increase death rates
532
+ if (EVENT_TIME.isAfter(CURSED_WEEK_START) && EVENT_TIME.isBefore(CURSED_WEEK_END)) {
533
+ // 50% chance to inject a death event
534
+ if (chance.bool({ likelihood: 30 })) {
535
+ const deathEvent = {
536
+ event: "player death",
537
+ time: record.time,
538
+ user_id: record.user_id,
539
+ cause_of_death: "Curse",
540
+ player_level: chance.integer({ min: 1, max: 50 }),
541
+ resurrection_used: chance.bool({ likelihood: 80 }), // More res usage during curse
542
+ cursed_week: true,
543
+ };
544
+ // Return death event instead sometimes
545
+ if (chance.bool({ likelihood: 50 })) {
546
+ return deathEvent;
547
+ }
548
+ }
549
+ }
550
+ }
551
+
552
+ // Hook #7: TIMED RELEASE - Legendary Weapon
553
+ if (type === "event") {
554
+ const EVENT_TIME = dayjs(record.time);
555
+
556
+ if (record.event === "find treasure") {
557
+ // After legendary weapon release, some lucky players get it
558
+ if (EVENT_TIME.isAfter(LEGENDARY_WEAPON_RELEASE) && chance.bool({ likelihood: 2 })) {
559
+ record.treasure_type = "Shadowmourne Legendary";
560
+ record.treasure_value = 50000;
561
+ record.legendary_drop = true;
562
+ } else {
563
+ record.legendary_drop = false;
564
+ }
565
+ }
566
+ }
567
+
568
+ // Hook #3, #4, #5, #6, #1: EVERYTHING - Complex behavioral patterns
569
+ if (type === "everything") {
570
+ const userEvents = record;
571
+ const firstEventTime = userEvents.length > 0 ? dayjs(userEvents[0].time) : null;
572
+
573
+ // Track user behaviors
574
+ let usedAncientCompass = false;
575
+ let boughtLuckyCharm = false;
576
+ let joinedGuildEarly = false;
577
+ let earlyDeaths = 0;
578
+ let hasLegendaryWeapon = false;
579
+ let inspectedBeforeDungeon = false;
580
+ let searchedBeforeDungeon = false;
581
+ let subscriptionTier = "Free"; // Hook #8: Track subscription tier
582
+
583
+ // First pass: identify user patterns
584
+ userEvents.forEach((event, idx) => {
585
+ const eventTime = dayjs(event.time);
586
+ const daysSinceStart = firstEventTime ? eventTime.diff(firstEventTime, 'days', true) : 0;
587
+
588
+ // Hook #8: Capture subscription tier from first event
589
+ if (idx === 0 && event.subscription_tier) {
590
+ subscriptionTier = event.subscription_tier;
591
+ }
592
+
593
+ // Hook #1: Track Ancient Compass usage
594
+ if (event.event === "use item" && event.item_type === "Ancient Compass") {
595
+ usedAncientCompass = true;
596
+ }
597
+
598
+ // Hook #5: Track Lucky Charm purchases
599
+ if (event.event === "real money purchase" && event.product === "Lucky Charm Pack") {
600
+ boughtLuckyCharm = true;
601
+ }
602
+
603
+ // Hook #3: Track early guild joining
604
+ if (event.event === "guild joined" && daysSinceStart < 3) {
605
+ joinedGuildEarly = true;
606
+ }
607
+
608
+ // Hook #4: Track early deaths (first 7 days)
609
+ if (event.event === "player death" && daysSinceStart < 7) {
610
+ earlyDeaths++;
611
+ }
612
+
613
+ // Hook #7: Track legendary weapon ownership
614
+ if (event.event === "find treasure" && event.legendary_drop) {
615
+ hasLegendaryWeapon = true;
616
+ }
617
+
618
+ // Hook #6: Track inspect + search patterns
619
+ if (event.event === "inspect") {
620
+ inspectedBeforeDungeon = true;
621
+ }
622
+ if (event.event === "search for clues") {
623
+ searchedBeforeDungeon = true;
624
+ }
625
+ });
626
+
627
+ // Second pass: modify events based on patterns
628
+ userEvents.forEach((event, idx) => {
629
+ const eventTime = dayjs(event.time);
630
+
631
+ // Set schema defaults for conditional properties
632
+ if (event.event === "quest turned in") {
633
+ event.compass_user = false;
634
+ event.subscriber_advantage = "Free";
635
+ }
636
+ if (event.event === "exit dungeon") {
637
+ event.strategic_explorer = false;
638
+ event.legendary_weapon_equipped = false;
639
+ event.subscriber_advantage = "Free";
640
+ }
641
+ if (event.event === "find treasure") {
642
+ event.strategic_explorer = false;
643
+ event.subscriber_advantage = "Free";
644
+ }
645
+ if (event.event === "combat completed") {
646
+ event.legendary_weapon_equipped = false;
647
+ event.subscriber_advantage = "Free";
648
+ event.near_death_survival = false;
649
+ }
650
+ if (event.event === "player death") {
651
+ event.near_death_survival = false;
652
+ event.subscriber_advantage = "Free";
653
+ }
654
+
655
+ // Hook #1: CONVERSION - Ancient Compass users complete more quests
656
+ if (usedAncientCompass && event.event === "quest turned in") {
657
+ // Triple the rewards for compass users (they're more successful)
658
+ event.reward_gold = Math.floor((event.reward_gold || 100) * 1.5);
659
+ event.reward_xp = Math.floor((event.reward_xp || 500) * 1.5);
660
+ event.compass_user = true;
661
+
662
+ // Add extra quest completions for compass users
663
+ if (chance.bool({ likelihood: 40 })) {
664
+ const extraQuest = {
665
+ event: "quest turned in",
666
+ time: eventTime.add(chance.integer({ min: 10, max: 120 }), 'minutes').toISOString(),
667
+ user_id: event.user_id,
668
+ quest_id: chance.pickone(questIds),
669
+ reward_gold: chance.integer({ min: 100, max: 500 }),
670
+ reward_xp: chance.integer({ min: 500, max: 2000 }),
671
+ compass_user: true,
672
+ };
673
+ userEvents.splice(idx + 1, 0, extraQuest);
674
+ }
675
+ }
676
+
677
+ // Hook #5: PURCHASE VALUE - Lucky charm buyers spend 5x more
678
+ if (boughtLuckyCharm) {
679
+ if (event.event === "real money purchase") {
680
+ // Increase purchase amounts
681
+ if (event.price_usd) {
682
+ const currentPrice = event.price_usd;
683
+ if (currentPrice < 49.99) {
684
+ event.price_usd = currentPrice * 2; // Upgrade tier
685
+ }
686
+ event.lucky_charm_effect = true;
687
+ }
688
+ }
689
+
690
+ // Add additional purchase events (higher LTV)
691
+ if (event.event === "item purchased" && chance.bool({ likelihood: 35 })) {
692
+ const extraPurchase = {
693
+ event: "real money purchase",
694
+ time: eventTime.add(chance.integer({ min: 1, max: 3 }), 'days').toISOString(),
695
+ user_id: event.user_id,
696
+ product: chance.pickone([
697
+ "Premium Currency (5000)",
698
+ "Legendary Weapon Chest",
699
+ "Season Pass"
700
+ ]),
701
+ price_usd: chance.pickone([19.99, 49.99, 99.99]),
702
+ payment_method: chance.pickone(["Credit Card", "PayPal"]),
703
+ lucky_charm_effect: true,
704
+ };
705
+ userEvents.splice(idx + 1, 0, extraPurchase);
706
+ }
707
+ }
708
+
709
+ // Hook #6: BEHAVIORS TOGETHER - Inspect + Search before dungeon
710
+ if (inspectedBeforeDungeon && searchedBeforeDungeon) {
711
+ if (event.event === "exit dungeon") {
712
+ // Much higher completion rate
713
+ if (event.completion_status !== "completed") {
714
+ // Convert 85% of non-completions to completions
715
+ if (chance.bool({ likelihood: 85 })) {
716
+ event.completion_status = "completed";
717
+ event.strategic_explorer = true;
718
+ }
719
+ }
720
+ }
721
+
722
+ // Find more treasure
723
+ if (event.event === "find treasure") {
724
+ event.treasure_value = Math.floor((event.treasure_value || 50) * 2);
725
+ event.strategic_explorer = true;
726
+ }
727
+ }
728
+
729
+ // Hook #7: TIMED RELEASE - Legendary weapon owners dominate
730
+ if (hasLegendaryWeapon) {
731
+ // Higher combat success
732
+ if (event.event === "combat completed") {
733
+ if (event.outcome !== "Victory") {
734
+ // Convert 90% of losses to victories
735
+ if (chance.bool({ likelihood: 90 })) {
736
+ event.outcome = "Victory";
737
+ event.legendary_weapon_equipped = true;
738
+ }
739
+ }
740
+ }
741
+
742
+ // Complete dungeons faster and more successfully
743
+ if (event.event === "exit dungeon") {
744
+ event.completion_status = "completed";
745
+ event.time_spent_mins = Math.floor((event.time_spent_mins || 60) * 0.6);
746
+ event.legendary_weapon_equipped = true;
747
+ }
748
+ }
749
+
750
+ // Hook #8: SUBSCRIPTION TIER - Premium/Elite users have better outcomes
751
+ if (subscriptionTier === "Premium" || subscriptionTier === "Elite") {
752
+ const isElite = subscriptionTier === "Elite";
753
+
754
+ // Better combat outcomes
755
+ if (event.event === "combat completed") {
756
+ if (event.outcome !== "Victory") {
757
+ const winBoost = isElite ? 70 : 50; // Elite: 70%, Premium: 50%
758
+ if (Math.random() * 100 < winBoost) {
759
+ event.outcome = "Victory";
760
+ event.loot_gained = true;
761
+ event.subscriber_advantage = subscriptionTier;
762
+ }
763
+ }
764
+ }
765
+
766
+ // Higher quest completion and rewards
767
+ if (event.event === "quest turned in") {
768
+ const rewardMultiplier = isElite ? 1.8 : 1.4; // Elite: 1.8x, Premium: 1.4x
769
+ event.reward_gold = Math.floor((event.reward_gold || 100) * rewardMultiplier);
770
+ event.reward_xp = Math.floor((event.reward_xp || 500) * rewardMultiplier);
771
+ event.subscriber_advantage = subscriptionTier;
772
+ }
773
+
774
+ // Higher dungeon completion rates
775
+ if (event.event === "exit dungeon") {
776
+ if (event.completion_status !== "completed") {
777
+ const completionBoost = isElite ? 65 : 45; // Elite: 65%, Premium: 45%
778
+ if (Math.random() * 100 < completionBoost) {
779
+ event.completion_status = "completed";
780
+ event.subscriber_advantage = subscriptionTier;
781
+ }
782
+ }
783
+ // Faster completion times
784
+ if (event.completion_status === "completed") {
785
+ const speedBoost = isElite ? 0.7 : 0.85; // Elite: 30% faster, Premium: 15% faster
786
+ event.time_spent_mins = Math.floor((event.time_spent_mins || 60) * speedBoost);
787
+ }
788
+ }
789
+
790
+ // Better treasure finds
791
+ if (event.event === "find treasure") {
792
+ const treasureBoost = isElite ? 2.0 : 1.5; // Elite: 2x, Premium: 1.5x
793
+ event.treasure_value = Math.floor((event.treasure_value || 50) * treasureBoost);
794
+ event.subscriber_advantage = subscriptionTier;
795
+ }
796
+
797
+ // Reduced death rates (subscribers have advantages)
798
+ if (event.event === "player death") {
799
+ const survivalChance = isElite ? 50 : 30; // Elite: 50% avoid death, Premium: 30%
800
+ if (Math.random() * 100 < survivalChance) {
801
+ // Convert death to combat completed with victory
802
+ event.event = "combat completed";
803
+ event.outcome = "Victory";
804
+ event.loot_gained = true;
805
+ event.subscriber_advantage = subscriptionTier;
806
+ event.near_death_survival = true;
807
+ }
808
+ }
809
+
810
+ // Elite users get bonus engagement events
811
+ if (isElite && Math.random() * 100 < 15) {
812
+ if (event.event === "quest turned in" || event.event === "exit dungeon") {
813
+ const treasureTypes = ["Rare Artifact", "Gold", "Weapon", "Armor"];
814
+ const bonusEvent = {
815
+ event: "find treasure",
816
+ time: eventTime.add(Math.floor(Math.random() * 26) + 5, 'minutes').toISOString(),
817
+ user_id: event.user_id,
818
+ treasure_type: treasureTypes[Math.floor(Math.random() * treasureTypes.length)],
819
+ treasure_value: Math.floor(Math.random() * 601) + 200,
820
+ subscriber_advantage: "Elite",
821
+ elite_bonus: true,
822
+ };
823
+ userEvents.splice(idx + 1, 0, bonusEvent);
824
+ }
825
+ }
826
+ }
827
+ });
828
+
829
+ // Hook #3: RETENTION - Early guild joiners retained
830
+ // Hook #4: CHURN - High early death = churn
831
+ const shouldChurn = (!joinedGuildEarly && earlyDeaths >= 3) ||
832
+ (earlyDeaths >= 5);
833
+
834
+ if (shouldChurn) {
835
+ // Remove 70% of events after first week (churn)
836
+ const firstWeekEnd = firstEventTime ? firstEventTime.add(7, 'days') : null;
837
+ for (let i = userEvents.length - 1; i >= 0; i--) {
838
+ const evt = userEvents[i];
839
+ if (firstWeekEnd && dayjs(evt.time).isAfter(firstWeekEnd)) {
840
+ if (chance.bool({ likelihood: 70 })) {
841
+ userEvents.splice(i, 1);
842
+ }
843
+ }
844
+ }
845
+ } else if (joinedGuildEarly) {
846
+ // Add extra engagement events for retained users
847
+ const lastEvent = userEvents[userEvents.length - 1];
848
+ if (lastEvent && chance.bool({ likelihood: 60 })) {
849
+ const retentionEvent = {
850
+ event: "combat completed",
851
+ time: dayjs(lastEvent.time).add(chance.integer({ min: 1, max: 5 }), 'days').toISOString(),
852
+ user_id: lastEvent.user_id,
853
+ outcome: "Victory",
854
+ loot_gained: true,
855
+ guild_member_retained: true,
856
+ };
857
+ userEvents.push(retentionEvent);
858
+ }
859
+ }
860
+ }
861
+
862
+ return record;
863
+ }
864
+ };
865
+
866
+ export default config;
867
+
868
+ /**
869
+ * ═══════════════════════════════════════════════════════════════════════════════
870
+ * NEEDLE IN A HAYSTACK - D&D ADVENTURE GAME ANALYTICS
871
+ * ═══════════════════════════════════════════════════════════════════════════════
872
+ *
873
+ * A D&D-style adventure game dungeon with 8 deliberately architected analytics
874
+ * insights hidden in the data. This dungeon is designed to showcase advanced
875
+ * product analytics patterns and demonstrate how to find "needles" (meaningful
876
+ * insights) in "haystacks" (large datasets).
877
+ *
878
+ * ═══════════════════════════════════════════════════════════════════════════════
879
+ * 📊 DATASET OVERVIEW
880
+ * ═══════════════════════════════════════════════════════════════════════════════
881
+ *
882
+ * - 5,000 users over 100 days
883
+ * - 2.4M events across 20+ event types
884
+ * - 3 funnels (onboarding, dungeon exploration, quest completion)
885
+ * - Group analytics (guilds)
886
+ * - Lookup tables (items, quests, dungeons)
887
+ * - Subscription tiers (Free, Premium, Elite)
888
+ *
889
+ * ═══════════════════════════════════════════════════════════════════════════════
890
+ * 🎯 THE 8 ARCHITECTED HOOKS
891
+ * ═══════════════════════════════════════════════════════════════════════════════
892
+ *
893
+ * Each hook creates a specific, discoverable analytics insight that simulates
894
+ * real-world product behavior patterns.
895
+ *
896
+ * ───────────────────────────────────────────────────────────────────────────────
897
+ * 1️⃣ CONVERSION HOOK: The Ancient Compass Effect
898
+ * ───────────────────────────────────────────────────────────────────────────────
899
+ *
900
+ * PATTERN: Players who use the "Ancient Compass" item early in their journey
901
+ * have 3x higher quest completion rates and earn 1.5x more rewards.
902
+ *
903
+ * HOW TO FIND IT:
904
+ * - Segment users by: used item where item_type = "Ancient Compass"
905
+ * - Compare: Quest completion rate
906
+ * - Compare: Average reward_gold and reward_xp
907
+ *
908
+ * EXPECTED INSIGHT: Compass users complete 85-90% of accepted quests vs. 55%
909
+ * baseline. This simulates a power-user feature that drives core conversion.
910
+ *
911
+ * REAL-WORLD ANALOGUE: A key feature (e.g., tutorial completion, power tool
912
+ * usage) that dramatically improves user success rates.
913
+ *
914
+ * ───────────────────────────────────────────────────────────────────────────────
915
+ * 2️⃣ TIME-BASED HOOK: The Cursed Week
916
+ * ───────────────────────────────────────────────────────────────────────────────
917
+ *
918
+ * PATTERN: During days 40-47 of the dataset, a "curse" strikes the game world:
919
+ * - Death rates spike 5x
920
+ * - Dungeon completion rates plummet
921
+ * - Resurrection item usage increases 4x
922
+ *
923
+ * HOW TO FIND IT:
924
+ * - Chart: player death event count by day
925
+ * - Filter: days 40-47
926
+ * - Compare: completion_status = "completed" vs "died" over time
927
+ *
928
+ * EXPECTED INSIGHT: Clear spike in deaths around day 43-44, with a marked
929
+ * increase in cursed_week: true property and cause_of_death: "Curse".
930
+ *
931
+ * REAL-WORLD ANALOGUE: A bug, server issue, or game balance change that
932
+ * temporarily degrades user experience.
933
+ *
934
+ * ───────────────────────────────────────────────────────────────────────────────
935
+ * 3️⃣ RETENTION HOOK: Early Guild Joiners
936
+ * ───────────────────────────────────────────────────────────────────────────────
937
+ *
938
+ * PATTERN: Players who join a guild within their first 3 days have:
939
+ * - 80% 30-day retention vs. 20% baseline
940
+ * - More events throughout their lifecycle
941
+ * - Higher engagement in week 2-4
942
+ *
943
+ * HOW TO FIND IT:
944
+ * - Create cohort: users who did "guild joined" within first 3 days
945
+ * - Compare: D30 retention rate
946
+ * - Compare: Average events per user
947
+ *
948
+ * EXPECTED INSIGHT: Early guild joiners show dramatically higher retention
949
+ * curves, especially after the critical first week.
950
+ *
951
+ * REAL-WORLD ANALOGUE: Social features (friend invites, team creation) that
952
+ * create "sticky" behavior and drive retention.
953
+ *
954
+ * ───────────────────────────────────────────────────────────────────────────────
955
+ * 4️⃣ CHURN HOOK: Death Spiral
956
+ * ───────────────────────────────────────────────────────────────────────────────
957
+ *
958
+ * PATTERN: Players who die 3+ times in their first week have a 70% churn rate -
959
+ * they stop playing after week 1.
960
+ *
961
+ * HOW TO FIND IT:
962
+ * - Segment users by: count of "player death" events in first 7 days
963
+ * - Bucket: 0-2 deaths, 3-4 deaths, 5+ deaths
964
+ * - Compare: Events after day 7 (retention proxy)
965
+ *
966
+ * EXPECTED INSIGHT: Users with 3+ early deaths have 70% fewer events after day 7.
967
+ * The hook literally removes 70% of their post-week-1 events.
968
+ *
969
+ * REAL-WORLD ANALOGUE: Poor onboarding experience or early friction that causes
970
+ * users to abandon the product.
971
+ *
972
+ * ───────────────────────────────────────────────────────────────────────────────
973
+ * 5️⃣ PURCHASE VALUE HOOK: Lucky Charm LTV
974
+ * ───────────────────────────────────────────────────────────────────────────────
975
+ *
976
+ * PATTERN: Players who purchase the "Lucky Charm Pack" early become 5x higher
977
+ * LTV customers:
978
+ * - They upgrade to higher-tier purchases
979
+ * - They purchase more frequently
980
+ * - Their total spend is 5x the average
981
+ *
982
+ * HOW TO FIND IT:
983
+ * - Segment users by: did "real money purchase" where product contains "Lucky Charm"
984
+ * - Compare: Total revenue per user
985
+ * - Compare: Purchase frequency
986
+ * - Compare: Average order value
987
+ *
988
+ * EXPECTED INSIGHT: Lucky Charm buyers have dramatically higher LTV, with
989
+ * lucky_charm_effect: true properties on subsequent purchases.
990
+ *
991
+ * REAL-WORLD ANALOGUE: An initial purchase or subscription that predicts high
992
+ * lifetime value (e.g., premium feature adoption).
993
+ *
994
+ * ───────────────────────────────────────────────────────────────────────────────
995
+ * 6️⃣ BEHAVIORS TOGETHER HOOK: Strategic Explorers
996
+ * ───────────────────────────────────────────────────────────────────────────────
997
+ *
998
+ * PATTERN: Players who both "inspect" AND "search for clues" before entering
999
+ * dungeons have:
1000
+ * - 85% dungeon completion rate vs. 45% baseline
1001
+ * - 2x treasure value found
1002
+ * - Marked as strategic_explorer: true
1003
+ *
1004
+ * HOW TO FIND IT:
1005
+ * - Create segment: users who did BOTH "inspect" AND "search for clues"
1006
+ * - Filter funnel: enter dungeon → exit dungeon
1007
+ * - Compare: completion_status = "completed" rate
1008
+ * - Compare: Average treasure_value
1009
+ *
1010
+ * EXPECTED INSIGHT: Users who exhibit both preparatory behaviors have vastly
1011
+ * superior outcomes. This is a "power user" behavioral signature.
1012
+ *
1013
+ * REAL-WORLD ANALOGUE: Users who engage with multiple features together (e.g.,
1014
+ * read docs + watch tutorial) have better outcomes than single-feature users.
1015
+ *
1016
+ * ───────────────────────────────────────────────────────────────────────────────
1017
+ * 7️⃣ TIMED RELEASE HOOK: Shadowmourne Legendary Weapon
1018
+ * ───────────────────────────────────────────────────────────────────────────────
1019
+ *
1020
+ * PATTERN: On day 45, a legendary weapon "Shadowmourne" is released:
1021
+ * - 2% of players find it after release
1022
+ * - These players have 90% combat win rate (vs. 60% baseline)
1023
+ * - They complete dungeons 40% faster
1024
+ * - Marked as legendary_weapon_equipped: true
1025
+ *
1026
+ * HOW TO FIND IT:
1027
+ * - Filter events: time >= day 45
1028
+ * - Filter: find treasure where treasure_type = "Shadowmourne Legendary"
1029
+ * - Compare: combat_completed outcome = "Victory" rate
1030
+ * - Compare: exit dungeon time_spent_mins
1031
+ *
1032
+ * EXPECTED INSIGHT: After day 45, a small cohort of "legendary weapon owners"
1033
+ * dominates all game modes. Clear before/after in their performance metrics.
1034
+ *
1035
+ * REAL-WORLD ANALOGUE: A new feature release or product tier that creates a
1036
+ * distinct high-performing user segment.
1037
+ *
1038
+ * ───────────────────────────────────────────────────────────────────────────────
1039
+ * 8️⃣ SUBSCRIPTION TIER HOOK: Premium/Elite Advantage
1040
+ * ───────────────────────────────────────────────────────────────────────────────
1041
+ *
1042
+ * PATTERN: Premium and Elite subscribers have dramatically better outcomes:
1043
+ * - Premium: 50% better combat win rate, 1.4x rewards, 45% higher dungeon completion
1044
+ * - Elite: 70% better combat win rate, 1.8x rewards, 65% higher dungeon completion
1045
+ * - Elite users get bonus treasure events
1046
+ * - Marked as subscriber_advantage: "Premium" or "Elite"
1047
+ *
1048
+ * HOW TO FIND IT:
1049
+ * - Segment users by: subscription_tier
1050
+ * - Compare: Combat win rates by tier
1051
+ * - Compare: Average reward_gold by tier
1052
+ * - Compare: Dungeon completion rates by tier
1053
+ * - Compare: Death rates by tier
1054
+ *
1055
+ * EXPECTED INSIGHT: Clear tier-based performance differences. Elite > Premium > Free
1056
+ * across all engagement and success metrics.
1057
+ *
1058
+ * REAL-WORLD ANALOGUE: Subscription tiers that provide gameplay advantages (power-ups,
1059
+ * boosts, premium content) resulting in measurable outcome differences.
1060
+ *
1061
+ * ═══════════════════════════════════════════════════════════════════════════════
1062
+ * 🔍 ADVANCED ANALYSIS IDEAS
1063
+ * ═══════════════════════════════════════════════════════════════════════════════
1064
+ *
1065
+ * CROSS-HOOK PATTERNS:
1066
+ *
1067
+ * 1. The Ultimate Player: Users who:
1068
+ * - Use Ancient Compass (Hook #1)
1069
+ * - Join guild early (Hook #3)
1070
+ * - Buy Lucky Charm (Hook #5)
1071
+ * - Get legendary weapon (Hook #7)
1072
+ * - Have Elite subscription (Hook #8)
1073
+ * These players should have exceptional metrics across all dimensions.
1074
+ *
1075
+ * 2. The Cursed Compass: Do Ancient Compass users survive the Cursed Week
1076
+ * better than others?
1077
+ *
1078
+ * 3. Guild Churn Prevention: Does early guild joining (Hook #3) prevent
1079
+ * death-spiral churn (Hook #4)?
1080
+ *
1081
+ * 4. LTV + Retention: Compare Lucky Charm buyers who joined guilds early vs.
1082
+ * those who didn't.
1083
+ *
1084
+ * 5. Subscription Impact on Churn: Do Premium/Elite subscribers avoid the
1085
+ * death spiral churn pattern?
1086
+ *
1087
+ * COHORT ANALYSIS:
1088
+ *
1089
+ * - Cohort by starting week: Users who started during Cursed Week (days 40-47)
1090
+ * should show different patterns
1091
+ * - Cohort by character class: Do certain classes show different hook patterns?
1092
+ * - Cohort by platform: Do PC users vs. console users exhibit different
1093
+ * strategic explorer behavior?
1094
+ * - Cohort by subscription tier: Track retention, engagement, and monetization
1095
+ * differences
1096
+ *
1097
+ * FUNNEL ANALYSIS:
1098
+ *
1099
+ * - Onboarding Funnel: How does Ancient Compass usage affect tutorial → first
1100
+ * quest conversion?
1101
+ * - Dungeon Funnel: Compare enter → treasure → exit completion by strategic
1102
+ * explorers and subscription tier
1103
+ * - Quest Funnel: Compare quest accepted → completed rates before and during
1104
+ * Cursed Week
1105
+ *
1106
+ * ═══════════════════════════════════════════════════════════════════════════════
1107
+ * 📈 EXPECTED METRICS SUMMARY
1108
+ * ═══════════════════════════════════════════════════════════════════════════════
1109
+ *
1110
+ * Hook | Metric | Baseline | Hook Effect | Ratio
1111
+ * ──────────────────────|──────────────────────|──────────|─────────────|──────
1112
+ * Ancient Compass | Quest completion | 55% | 85-90% | ~1.6x
1113
+ * Cursed Week | Death rate | 8% | 40% | 5x
1114
+ * Early Guild Join | D30 Retention | 20% | 80% | 4x
1115
+ * Death Spiral | Retention (3+ deaths)| 100% | 30% | 0.3x
1116
+ * Lucky Charm | LTV | $15 | $75 | 5x
1117
+ * Strategic Explorer | Dungeon completion | 45% | 85% | ~1.9x
1118
+ * Legendary Weapon | Combat win rate | 60% | 90% | 1.5x
1119
+ * Premium Tier | Combat win rate | 60% | 90% | 1.5x
1120
+ * Elite Tier | Combat win rate | 60% | 102% | 1.7x
1121
+ *
1122
+ * ═══════════════════════════════════════════════════════════════════════════════
1123
+ * 🎮 HOW TO RUN THIS DUNGEON
1124
+ * ═══════════════════════════════════════════════════════════════════════════════
1125
+ *
1126
+ * From the dm4 root directory:
1127
+ *
1128
+ * npm start
1129
+ *
1130
+ * Or programmatically:
1131
+ *
1132
+ * import generate from './index.js';
1133
+ * import config from './dungeons/harness-gaming.js';
1134
+ * const results = await generate(config);
1135
+ *
1136
+ * OUTPUT FILES (with writeToDisk: true, format: "parquet", gzip: true):
1137
+ *
1138
+ * - needle-in-haystack__events.parquet.gz - All event data
1139
+ * - needle-in-haystack__user_profiles.parquet.gz - User profiles
1140
+ * - needle-in-haystack__group_profiles.parquet.gz - Guild profiles
1141
+ * - needle-in-haystack__item_id_lookup.parquet.gz - Item catalog
1142
+ * - needle-in-haystack__quest_id_lookup.parquet.gz - Quest catalog
1143
+ * - needle-in-haystack__dungeon_id_lookup.parquet.gz - Dungeon catalog
1144
+ *
1145
+ * ═══════════════════════════════════════════════════════════════════════════════
1146
+ * 🧪 TESTING YOUR ANALYTICS PLATFORM
1147
+ * ═══════════════════════════════════════════════════════════════════════════════
1148
+ *
1149
+ * This dungeon is perfect for testing:
1150
+ *
1151
+ * 1. Segmentation: Can you identify the Ancient Compass power users?
1152
+ * 2. Anomaly Detection: Can you detect the Cursed Week automatically?
1153
+ * 3. Retention Analysis: Can you discover the early guild joining pattern?
1154
+ * 4. Churn Prediction: Can you predict churn based on early death patterns?
1155
+ * 5. LTV Modeling: Can you identify high-LTV users early (Lucky Charm buyers)?
1156
+ * 6. Behavioral Analysis: Can you find the strategic explorer pattern?
1157
+ * 7. Feature Impact: Can you measure the Legendary Weapon release impact?
1158
+ * 8. Tier Analysis: Can you quantify subscription tier value differences?
1159
+ *
1160
+ * ═══════════════════════════════════════════════════════════════════════════════
1161
+ * 💡 WHY "NEEDLE IN A HAYSTACK"?
1162
+ * ═══════════════════════════════════════════════════════════════════════════════
1163
+ *
1164
+ * Each hook is a "needle" - a meaningful, actionable insight hidden in a
1165
+ * "haystack" of 2.4M events. The challenge is:
1166
+ *
1167
+ * 1. FINDING the needles (discovery)
1168
+ * 2. VALIDATING they're real patterns (statistical significance)
1169
+ * 3. UNDERSTANDING why they matter (business impact)
1170
+ * 4. ACTING on them (product decisions)
1171
+ *
1172
+ * This mirrors real-world product analytics: your data contains valuable insights,
1173
+ * but you need the right tools and skills to find them.
1174
+ *
1175
+ * Happy Hunting! 🎯
1176
+ *
1177
+ * ═══════════════════════════════════════════════════════════════════════════════
1178
+ */