@sbugallo/pokecode 0.2.1 → 0.3.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 (128) hide show
  1. package/README.md +17 -11
  2. package/dist/adapters/opencode/tui/choices/cards.d.ts +4 -0
  3. package/dist/adapters/opencode/tui/choices/cards.d.ts.map +1 -1
  4. package/dist/adapters/opencode/tui/choices/cards.jsx +6 -6
  5. package/dist/adapters/opencode/tui/choices/cards.jsx.map +1 -1
  6. package/dist/adapters/opencode/tui/choices/encounter.d.ts +2 -0
  7. package/dist/adapters/opencode/tui/choices/encounter.d.ts.map +1 -1
  8. package/dist/adapters/opencode/tui/choices/encounter.jsx +1 -1
  9. package/dist/adapters/opencode/tui/choices/encounter.jsx.map +1 -1
  10. package/dist/adapters/opencode/tui/components/image-protocol.d.ts +31 -0
  11. package/dist/adapters/opencode/tui/components/image-protocol.d.ts.map +1 -0
  12. package/dist/adapters/opencode/tui/components/image-protocol.js +83 -0
  13. package/dist/adapters/opencode/tui/components/image-protocol.js.map +1 -0
  14. package/dist/adapters/opencode/tui/components/sprite.d.ts +2 -0
  15. package/dist/adapters/opencode/tui/components/sprite.d.ts.map +1 -1
  16. package/dist/adapters/opencode/tui/components/sprite.jsx +1 -1
  17. package/dist/adapters/opencode/tui/components/sprite.jsx.map +1 -1
  18. package/dist/adapters/opencode/tui/pc/actions.d.ts +2 -0
  19. package/dist/adapters/opencode/tui/pc/actions.d.ts.map +1 -1
  20. package/dist/adapters/opencode/tui/pc/actions.jsx +1 -1
  21. package/dist/adapters/opencode/tui/pc/actions.jsx.map +1 -1
  22. package/dist/adapters/opencode/tui/pc/details.d.ts +2 -0
  23. package/dist/adapters/opencode/tui/pc/details.d.ts.map +1 -1
  24. package/dist/adapters/opencode/tui/pc/details.jsx +1 -1
  25. package/dist/adapters/opencode/tui/pc/details.jsx.map +1 -1
  26. package/dist/adapters/opencode/tui/pc/dialog.d.ts +2 -0
  27. package/dist/adapters/opencode/tui/pc/dialog.d.ts.map +1 -1
  28. package/dist/adapters/opencode/tui/pc/dialog.jsx +1 -1
  29. package/dist/adapters/opencode/tui/pc/dialog.jsx.map +1 -1
  30. package/dist/adapters/opencode/tui/plugin.d.ts.map +1 -1
  31. package/dist/adapters/opencode/tui/plugin.jsx +8 -0
  32. package/dist/adapters/opencode/tui/plugin.jsx.map +1 -1
  33. package/dist/adapters/opencode/tui/sidebar/register.d.ts +2 -0
  34. package/dist/adapters/opencode/tui/sidebar/register.d.ts.map +1 -1
  35. package/dist/adapters/opencode/tui/sidebar/register.jsx +1 -1
  36. package/dist/adapters/opencode/tui/sidebar/register.jsx.map +1 -1
  37. package/dist/adapters/opencode/tui/sidebar/view.d.ts +4 -0
  38. package/dist/adapters/opencode/tui/sidebar/view.d.ts.map +1 -1
  39. package/dist/adapters/opencode/tui/sidebar/view.jsx +9 -9
  40. package/dist/adapters/opencode/tui/sidebar/view.jsx.map +1 -1
  41. package/dist/adapters/opencode/tui/state/cleanup.d.ts +1 -0
  42. package/dist/adapters/opencode/tui/state/cleanup.d.ts.map +1 -1
  43. package/dist/adapters/opencode/tui/state/cleanup.js +1 -0
  44. package/dist/adapters/opencode/tui/state/cleanup.js.map +1 -1
  45. package/dist/adapters/opencode/tui/travel/actions.d.ts +2 -0
  46. package/dist/adapters/opencode/tui/travel/actions.d.ts.map +1 -1
  47. package/dist/adapters/opencode/tui/travel/actions.jsx +1 -1
  48. package/dist/adapters/opencode/tui/travel/actions.jsx.map +1 -1
  49. package/dist/adapters/opencode/tui/travel/dialog.d.ts +2 -0
  50. package/dist/adapters/opencode/tui/travel/dialog.d.ts.map +1 -1
  51. package/dist/adapters/opencode/tui/travel/dialog.jsx +1 -1
  52. package/dist/adapters/opencode/tui/travel/dialog.jsx.map +1 -1
  53. package/dist/adapters/sqlite/game-repository.d.ts +2 -1
  54. package/dist/adapters/sqlite/game-repository.d.ts.map +1 -1
  55. package/dist/adapters/sqlite/game-repository.js +9 -1
  56. package/dist/adapters/sqlite/game-repository.js.map +1 -1
  57. package/dist/adapters/sqlite/queries/game-state.d.ts +2 -1
  58. package/dist/adapters/sqlite/queries/game-state.d.ts.map +1 -1
  59. package/dist/adapters/sqlite/queries/game-state.js +9 -3
  60. package/dist/adapters/sqlite/queries/game-state.js.map +1 -1
  61. package/dist/application/contracts/game.d.ts +3 -2
  62. package/dist/application/contracts/game.d.ts.map +1 -1
  63. package/dist/application/contracts/game.js +3 -2
  64. package/dist/application/contracts/game.js.map +1 -1
  65. package/dist/application/game.d.ts.map +1 -1
  66. package/dist/application/game.js +5 -1
  67. package/dist/application/game.js.map +1 -1
  68. package/dist/application/ports/game.d.ts +2 -1
  69. package/dist/application/ports/game.d.ts.map +1 -1
  70. package/dist/application/use-cases/record-usage.d.ts.map +1 -1
  71. package/dist/application/use-cases/record-usage.js +17 -4
  72. package/dist/application/use-cases/record-usage.js.map +1 -1
  73. package/dist/domain/content/catalog.d.ts +4 -0
  74. package/dist/domain/content/catalog.d.ts.map +1 -1
  75. package/dist/domain/content/catalog.js +17 -0
  76. package/dist/domain/content/catalog.js.map +1 -1
  77. package/dist/domain/content/catalogs/alola-locations-catalog.d.ts +1 -0
  78. package/dist/domain/content/catalogs/alola-locations-catalog.d.ts.map +1 -1
  79. package/dist/domain/content/catalogs/alola-locations-catalog.js +1 -0
  80. package/dist/domain/content/catalogs/alola-locations-catalog.js.map +1 -1
  81. package/dist/domain/content/catalogs/galar-locations-catalog.d.ts +1 -0
  82. package/dist/domain/content/catalogs/galar-locations-catalog.d.ts.map +1 -1
  83. package/dist/domain/content/catalogs/galar-locations-catalog.js +1 -0
  84. package/dist/domain/content/catalogs/galar-locations-catalog.js.map +1 -1
  85. package/dist/domain/content/catalogs/hoenn-locations-catalog.d.ts +1 -0
  86. package/dist/domain/content/catalogs/hoenn-locations-catalog.d.ts.map +1 -1
  87. package/dist/domain/content/catalogs/hoenn-locations-catalog.js +1 -0
  88. package/dist/domain/content/catalogs/hoenn-locations-catalog.js.map +1 -1
  89. package/dist/domain/content/catalogs/johto-locations-catalog.d.ts +1 -0
  90. package/dist/domain/content/catalogs/johto-locations-catalog.d.ts.map +1 -1
  91. package/dist/domain/content/catalogs/johto-locations-catalog.js +1 -0
  92. package/dist/domain/content/catalogs/johto-locations-catalog.js.map +1 -1
  93. package/dist/domain/content/catalogs/kalos-locations-catalog.d.ts +1 -0
  94. package/dist/domain/content/catalogs/kalos-locations-catalog.d.ts.map +1 -1
  95. package/dist/domain/content/catalogs/kalos-locations-catalog.js +1 -0
  96. package/dist/domain/content/catalogs/kalos-locations-catalog.js.map +1 -1
  97. package/dist/domain/content/catalogs/kanto-locations-catalog.d.ts +1 -0
  98. package/dist/domain/content/catalogs/kanto-locations-catalog.d.ts.map +1 -1
  99. package/dist/domain/content/catalogs/kanto-locations-catalog.js +1 -0
  100. package/dist/domain/content/catalogs/kanto-locations-catalog.js.map +1 -1
  101. package/dist/domain/content/catalogs/paldea-locations-catalog.d.ts +1 -0
  102. package/dist/domain/content/catalogs/paldea-locations-catalog.d.ts.map +1 -1
  103. package/dist/domain/content/catalogs/paldea-locations-catalog.js +1 -0
  104. package/dist/domain/content/catalogs/paldea-locations-catalog.js.map +1 -1
  105. package/dist/domain/content/catalogs/sinnoh-locations-catalog.d.ts +1 -0
  106. package/dist/domain/content/catalogs/sinnoh-locations-catalog.d.ts.map +1 -1
  107. package/dist/domain/content/catalogs/sinnoh-locations-catalog.js +1 -0
  108. package/dist/domain/content/catalogs/sinnoh-locations-catalog.js.map +1 -1
  109. package/dist/domain/content/catalogs/unova-locations-catalog.d.ts +1 -0
  110. package/dist/domain/content/catalogs/unova-locations-catalog.d.ts.map +1 -1
  111. package/dist/domain/content/catalogs/unova-locations-catalog.js +1 -0
  112. package/dist/domain/content/catalogs/unova-locations-catalog.js.map +1 -1
  113. package/dist/domain/content/schema.d.ts +1 -0
  114. package/dist/domain/content/schema.d.ts.map +1 -1
  115. package/dist/domain/content/schema.js +2 -0
  116. package/dist/domain/content/schema.js.map +1 -1
  117. package/dist/domain/exploration/exploration.d.ts +20 -0
  118. package/dist/domain/exploration/exploration.d.ts.map +1 -1
  119. package/dist/domain/exploration/exploration.js +17 -0
  120. package/dist/domain/exploration/exploration.js.map +1 -1
  121. package/dist/domain/usage/usage.d.ts +3 -3
  122. package/dist/domain/usage/usage.d.ts.map +1 -1
  123. package/dist/domain/usage/usage.js +4 -2
  124. package/dist/domain/usage/usage.js.map +1 -1
  125. package/dist/index.js +67 -10
  126. package/dist/rpc.js +8 -2
  127. package/dist/tui.js +195 -36
  128. package/package.json +1 -1
@@ -21,6 +21,23 @@ export const explorationStatusSchema = z.object({
21
21
  locationUnlockThreshold: z.number().int().positive(),
22
22
  regionComplete: z.boolean(),
23
23
  });
24
+ /**
25
+ * Token cost to advance from the location at `index` to the next one.
26
+ *
27
+ * Follows a region-length-normalized power curve, T(I) = base·(I+1)^exponent·
28
+ * (championIndex+1)^regionExponent, calibrated against main-series gymLeader and
29
+ * champion ace levels so party level tracks story progress. Beyond the champion
30
+ * (postgame/DLC locations) the cost is capped at the champion-approach cost:
31
+ * the curve was fitted on story data only, and extrapolating it would price
32
+ * Galar's DLC tail at tens of millions of tokens.
33
+ */
34
+ export function locationUnlockThreshold(input) {
35
+ const capped = Math.min(Math.max(input.index, 0), input.championIndex);
36
+ const cumulative = (i) => input.curve.baseTokens *
37
+ (i + 1) ** input.curve.exponent *
38
+ (input.championIndex + 1) ** input.curve.regionExponent;
39
+ return Math.round(cumulative(capped + 1) - cumulative(capped));
40
+ }
24
41
  export function calculateUnlockProgress(input) {
25
42
  if (!input.currentLocationIsLatestUnlocked)
26
43
  return { kind: "not-latest" };
@@ -1 +1 @@
1
- {"version":3,"file":"exploration.js","sourceRoot":"","sources":["../../../src/domain/exploration/exploration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,EAAE,EAAE,gBAAgB;IACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;IACrB,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;CAC3B,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,OAAO,EAAE,CAAC;SACP,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;QACpB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;QACtB,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC;KACzC,CAAC,CACH;SACA,OAAO,CAAC,EAAE,CAAC;IACd,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,sBAAsB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACtD,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACpD,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;CAC5B,CAAC,CAAA;AAQF,MAAM,UAAU,uBAAuB,CAAC,KAMvC;IACC,IAAI,CAAC,KAAK,CAAC,+BAA+B;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAA;IACzE,IAAI,CAAC,KAAK,CAAC,eAAe;QAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,KAAK,CAAC,aAAa,EAAE,CAAA;IAC/F,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,YAAY,CAAA;IAC3D,OAAO,UAAU,GAAG,KAAK,CAAC,SAAS;QACjC,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE;QACtC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,CAAA;AACvC,CAAC;AAGD,MAAM,UAAU,yBAAyB,CAAC,KAGzC;IACC,IAAI,CAAC,KAAK,CAAC,cAAc;QAAE,OAAO,kBAAkB,CAAA;IACpD,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAA;AACvD,CAAC;AAOD,MAAM,UAAU,uBAAuB,CAAC,KAIvC;IACC,IAAI,CAAC,KAAK,CAAC,YAAY;QAAE,OAAO,gBAAgB,CAAA;IAChD,IAAI,CAAC,KAAK,CAAC,qBAAqB;QAAE,OAAO,mBAAmB,CAAA;IAC5D,IAAI,KAAK,CAAC,oBAAoB;QAAE,OAAO,iBAAiB,CAAA;IACxD,OAAO,SAAS,CAAA;AAClB,CAAC"}
1
+ {"version":3,"file":"exploration.js","sourceRoot":"","sources":["../../../src/domain/exploration/exploration.ts"],"names":[],"mappings":"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"}
@@ -6,9 +6,9 @@ export type TokenUsage = {
6
6
  readonly cacheWriteTokens: number;
7
7
  };
8
8
  export declare function totalTokens(input: TokenUsage): number;
9
- export declare function experienceFromTokens(tokenCount: number, config: {
10
- readonly xpTokensPerPoint: number;
11
- }): number;
9
+ /** Fixed rate the unlock curve was calibrated against: 1000 tokens = 1 XP. */
10
+ export declare const tokensPerExperiencePoint = 1000;
11
+ export declare function experienceFromTokens(tokenCount: number): number;
12
12
  export declare function usageReceiptKey(input: {
13
13
  readonly sessionId: string;
14
14
  readonly messageId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../src/domain/usage/usage.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CAClC,CAAA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAQrD;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE;IAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC5C,MAAM,CAER;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B,GAAG,MAAM,CAET;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB,GAAG,WAAW,GAAG,UAAU,GAAG,kBAAkB,GAAG,SAAS,CAK5D"}
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../src/domain/usage/usage.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CAClC,CAAA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAQrD;AAED,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB,OAAQ,CAAA;AAE7C,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B,GAAG,MAAM,CAET;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB,GAAG,WAAW,GAAG,UAAU,GAAG,kBAAkB,GAAG,SAAS,CAK5D"}
@@ -5,8 +5,10 @@ export function totalTokens(input) {
5
5
  input.cacheReadTokens +
6
6
  input.cacheWriteTokens);
7
7
  }
8
- export function experienceFromTokens(tokenCount, config) {
9
- return tokenCount / config.xpTokensPerPoint;
8
+ /** Fixed rate the unlock curve was calibrated against: 1000 tokens = 1 XP. */
9
+ export const tokensPerExperiencePoint = 1_000;
10
+ export function experienceFromTokens(tokenCount) {
11
+ return tokenCount / tokensPerExperiencePoint;
10
12
  }
11
13
  export function usageReceiptKey(input) {
12
14
  return `${input.sessionId}:${input.messageId}`;
@@ -1 +1 @@
1
- {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/domain/usage/usage.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,OAAO,CACL,KAAK,CAAC,WAAW;QACjB,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,eAAe;QACrB,KAAK,CAAC,eAAe;QACrB,KAAK,CAAC,gBAAgB,CACvB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,UAAkB,EAClB,MAA6C;IAE7C,OAAO,UAAU,GAAG,MAAM,CAAC,gBAAgB,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAG/B;IACC,OAAO,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,EAAE,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAIlC;IACC,IAAI,KAAK,CAAC,SAAS;QAAE,OAAO,WAAW,CAAA;IACvC,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,UAAU,CAAA;IACpC,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,kBAAkB,CAAA;IAC3C,OAAO,SAAS,CAAA;AAClB,CAAC"}
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/domain/usage/usage.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,OAAO,CACL,KAAK,CAAC,WAAW;QACjB,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,eAAe;QACrB,KAAK,CAAC,eAAe;QACrB,KAAK,CAAC,gBAAgB,CACvB,CAAA;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAA;AAE7C,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,OAAO,UAAU,GAAG,wBAAwB,CAAA;AAC9C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAG/B;IACC,OAAO,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,EAAE,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAIlC;IACC,IAAI,KAAK,CAAC,SAAS;QAAE,OAAO,WAAW,CAAA;IACvC,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,UAAU,CAAA;IACpC,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,kBAAkB,CAAA;IAC3C,OAAO,SAAS,CAAA;AAClB,CAAC"}
package/dist/index.js CHANGED
@@ -2088,6 +2088,7 @@ var alolaLocationsCatalog = {
2088
2088
  maximumLevel: 50
2089
2089
  }
2090
2090
  ],
2091
+ championLocationId: "alola-pokemon-league",
2091
2092
  locations: [
2092
2093
  {
2093
2094
  id: "iki-town",
@@ -8093,6 +8094,7 @@ var galarLocationsCatalog = {
8093
8094
  maximumLevel: 70
8094
8095
  }
8095
8096
  ],
8097
+ championLocationId: "energy-plant",
8096
8098
  locations: [
8097
8099
  {
8098
8100
  id: "postwick",
@@ -16165,6 +16167,7 @@ var hoennLocationsCatalog = {
16165
16167
  maximumLevel: 5
16166
16168
  }
16167
16169
  ],
16170
+ championLocationId: "ever-grande-city",
16168
16171
  locations: [
16169
16172
  {
16170
16173
  id: "littleroot-town",
@@ -19719,6 +19722,7 @@ var johtoLocationsCatalog = {
19719
19722
  maximumLevel: 40
19720
19723
  }
19721
19724
  ],
19725
+ championLocationId: "johto-indigo-plateau",
19722
19726
  locations: [
19723
19727
  {
19724
19728
  id: "new-bark-town",
@@ -23871,6 +23875,7 @@ var kalosLocationsCatalog = {
23871
23875
  maximumLevel: 70
23872
23876
  }
23873
23877
  ],
23878
+ championLocationId: "kalos-pokemon-league",
23874
23879
  locations: [
23875
23880
  {
23876
23881
  id: "vaniville-town",
@@ -28199,6 +28204,7 @@ var kantoLocationsCatalog = {
28199
28204
  "squirtle"
28200
28205
  ],
28201
28206
  specialEncounters: [],
28207
+ championLocationId: "indigo-plateau",
28202
28208
  locations: [
28203
28209
  {
28204
28210
  id: "pallet-town",
@@ -43880,6 +43886,7 @@ var paldeaLocationsCatalog = {
43880
43886
  "quaxly"
43881
43887
  ],
43882
43888
  specialEncounters: [],
43889
+ championLocationId: "paldea-pokemon-league",
43883
43890
  locations: [
43884
43891
  {
43885
43892
  id: "cabo-poco",
@@ -166726,6 +166733,7 @@ var sinnohLocationsCatalog = {
166726
166733
  maximumLevel: 50
166727
166734
  }
166728
166735
  ],
166736
+ championLocationId: "victory-road",
166729
166737
  locations: [
166730
166738
  {
166731
166739
  id: "twinleaf-town",
@@ -173929,6 +173937,7 @@ var unovaLocationsCatalog = {
173929
173937
  maximumLevel: 15
173930
173938
  }
173931
173939
  ],
173940
+ championLocationId: "unova-pokemon-league",
173932
173941
  locations: [
173933
173942
  {
173934
173943
  id: "nuvema-town",
@@ -180519,6 +180528,7 @@ var regionSchema = namedIdSchema.extend({
180519
180528
  locations: z3.array(locationSchema).min(1),
180520
180529
  starterSpeciesIds: z3.array(z3.string().min(1)).length(3),
180521
180530
  starterCatchLocationId: z3.string().min(1),
180531
+ championLocationId: z3.string().min(1),
180522
180532
  specials: z3.array(specialSchema)
180523
180533
  });
180524
180534
  var speciesSchema = namedIdSchema.extend({
@@ -180612,6 +180622,7 @@ var catalog = generatedCatalogSchema.parse({
180612
180622
  localization: region.localization,
180613
180623
  starterSpeciesIds: regionalCatalog.starterPokemons,
180614
180624
  starterCatchLocationId: locations[0]?.id ?? "",
180625
+ championLocationId: regionalCatalog.championLocationId,
180615
180626
  specials: specialsForCatalog(regionalCatalog).flatMap((special) => {
180616
180627
  const pokemon = pokemonById.get(special.id);
180617
180628
  const ability = englishAbilityName(pokemon?.abilities[0]);
@@ -180660,6 +180671,12 @@ var catalog = generatedCatalogSchema.parse({
180660
180671
  ]))))
180661
180672
  });
180662
180673
  var generatedContentCatalog = catalog;
180674
+ var championIndexByRegion = new Map(catalog.regions.map((region) => {
180675
+ const index = region.locations.findIndex((location) => location.id === region.championLocationId);
180676
+ if (index < 0)
180677
+ throw new Error(`Unknown championLocationId ${region.championLocationId}`);
180678
+ return [region.id, index];
180679
+ }));
180663
180680
  var regionsById = new Map(catalog.regions.map((region) => [region.id, region]));
180664
180681
  var speciesById = new Map([...catalog.species, ...catalog.regionalForms].map((species) => [species.id, species]));
180665
180682
  var movesById = new Map(movesCatalog.map((move) => [move.id, move]));
@@ -180712,6 +180729,13 @@ function nextLocation(regionId, locationId) {
180712
180729
  const index = locations.findIndex((location) => location.id === locationId);
180713
180730
  return index < 0 ? null : locations[index + 1] ?? null;
180714
180731
  }
180732
+ function championIndexForRegion(regionId) {
180733
+ return championIndexByRegion.get(regionId) ?? null;
180734
+ }
180735
+ function locationIndexFor(regionId, locationId) {
180736
+ const index = locationsForRegion(regionId).findIndex((location) => location.id === locationId);
180737
+ return index < 0 ? null : index;
180738
+ }
180715
180739
  function startersForRegion(regionId, language = "en") {
180716
180740
  return regionsById.get(regionId)?.starterSpeciesIds.flatMap((speciesId) => {
180717
180741
  const species = speciesById.get(speciesId);
@@ -180922,6 +180946,11 @@ var explorationStatusSchema = z5.object({
180922
180946
  locationUnlockThreshold: z5.number().int().positive(),
180923
180947
  regionComplete: z5.boolean()
180924
180948
  });
180949
+ function locationUnlockThreshold(input) {
180950
+ const capped = Math.min(Math.max(input.index, 0), input.championIndex);
180951
+ const cumulative = (i) => input.curve.baseTokens * (i + 1) ** input.curve.exponent * (input.championIndex + 1) ** input.curve.regionExponent;
180952
+ return Math.round(cumulative(capped + 1) - cumulative(capped));
180953
+ }
180925
180954
  function calculateUnlockProgress(input) {
180926
180955
  if (!input.currentLocationIsLatestUnlocked)
180927
180956
  return { kind: "not-latest" };
@@ -181016,10 +181045,11 @@ var starterChoiceResultSchema = z9.object({
181016
181045
  });
181017
181046
  var gameplayConfigSchema = z9.object({
181018
181047
  pauseOnPendingChoice: z9.boolean().default(true),
181019
- xpTokensPerPoint: z9.number().int().positive().default(1000),
181020
181048
  encounterMinimumTokens: z9.number().int().positive().default(200000),
181021
181049
  encounterMaximumTokens: z9.number().int().positive().default(400000),
181022
- locationUnlockTokens: z9.number().int().positive().default(2160000)
181050
+ locationUnlockBaseTokens: z9.number().int().positive().default(4214000),
181051
+ locationUnlockExponent: z9.number().positive().default(2.64),
181052
+ locationUnlockRegionExponent: z9.number().default(-1.72)
181023
181053
  });
181024
181054
  var usageInputSchema = z9.object({
181025
181055
  sessionId: z9.string().min(1),
@@ -181515,7 +181545,7 @@ function trainerIdForQueries(database) {
181515
181545
 
181516
181546
  // src/adapters/sqlite/queries/game-state.ts
181517
181547
  function createSqliteGameStateQuery(database) {
181518
- return (locationUnlockThreshold) => {
181548
+ return (unlockCurve) => {
181519
181549
  const trainer = database.query("SELECT id, current_region_id AS regionId, current_location_id AS locationId FROM trainers LIMIT 1").get();
181520
181550
  if (trainer === null) {
181521
181551
  return gameStateSchema.parse({
@@ -181607,6 +181637,9 @@ function createSqliteGameStateQuery(database) {
181607
181637
  const progress = database.query("SELECT token_count AS tokenCount FROM location_unlock_progress WHERE trainer_id = ?1").get(trainer.id);
181608
181638
  const regionProgress = database.query("SELECT region_id AS regionId, completed FROM region_progress WHERE trainer_id = ?1").all(trainer.id);
181609
181639
  const progressByRegion = new Map(regionProgress.map((region) => [region.regionId, region]));
181640
+ const locationIndex = locationIndexFor(trainer.regionId, trainer.locationId);
181641
+ const championIndex = championIndexForRegion(trainer.regionId);
181642
+ const unlockThreshold = locationIndex === null || championIndex === null ? unlockCurve.baseTokens : locationUnlockThreshold({ index: locationIndex, championIndex, curve: unlockCurve });
181610
181643
  return gameStateSchema.parse({
181611
181644
  phase: "active",
181612
181645
  message: `Your ${trainer.regionId} adventure begins at ${trainer.locationId}.`,
@@ -181639,7 +181672,7 @@ function createSqliteGameStateQuery(database) {
181639
181672
  encounterless: location.encounterless
181640
181673
  })),
181641
181674
  locationUnlockProgress: progress?.tokenCount ?? 0,
181642
- locationUnlockThreshold,
181675
+ locationUnlockThreshold: unlockThreshold,
181643
181676
  regionComplete: progressByRegion.get(trainer.regionId)?.completed === 1
181644
181677
  }
181645
181678
  });
@@ -181962,7 +181995,15 @@ function openGameRepository(path = globalDatabasePath()) {
181962
181995
  database.run("PRAGMA journal_mode = WAL");
181963
181996
  });
181964
181997
  const queryState = createSqliteGameStateQuery(database);
181965
- const readState = (locationUnlockThreshold = gameplayConfigSchema.parse({}).locationUnlockTokens) => queryState(locationUnlockThreshold);
181998
+ const defaultUnlockCurve = () => {
181999
+ const config = gameplayConfigSchema.parse({});
182000
+ return {
182001
+ baseTokens: config.locationUnlockBaseTokens,
182002
+ exponent: config.locationUnlockExponent,
182003
+ regionExponent: config.locationUnlockRegionExponent
182004
+ };
182005
+ };
182006
+ const readState = (unlockCurve = defaultUnlockCurve()) => queryState(unlockCurve);
181966
182007
  const starterSelectionStore = createSqliteStarterSelectionStore(database, readState);
181967
182008
  const collectionQueries = createSqliteCollectionQueries(database);
181968
182009
  const collection = () => {
@@ -183022,8 +183063,9 @@ function createGameCommands(dependencies) {
183022
183063
  function totalTokens(input) {
183023
183064
  return input.inputTokens + input.outputTokens + input.reasoningTokens + input.cacheReadTokens + input.cacheWriteTokens;
183024
183065
  }
183025
- function experienceFromTokens(tokenCount, config) {
183026
- return tokenCount / config.xpTokensPerPoint;
183066
+ var tokensPerExperiencePoint = 1000;
183067
+ function experienceFromTokens(tokenCount) {
183068
+ return tokenCount / tokensPerExperiencePoint;
183027
183069
  }
183028
183070
  function usageReceiptKey(input) {
183029
183071
  return `${input.sessionId}:${input.messageId}`;
@@ -183060,7 +183102,7 @@ function createRecordUsage(dependencies) {
183060
183102
  return disposition;
183061
183103
  if (trainer === null)
183062
183104
  return "inactive";
183063
- stores.pokemon.addPartyExperience(trainer.id, experienceFromTokens(tokenCount, config));
183105
+ stores.pokemon.addPartyExperience(trainer.id, experienceFromTokens(tokenCount));
183064
183106
  resolveUsageLevels(stores, trainer.id, trainer.regionId, input.completedAt, dependencies.createId);
183065
183107
  advanceLocationUnlock(stores, trainer, tokenCount, config, input.completedAt, dependencies.createId);
183066
183108
  advanceUsageEncounters(stores, trainer.id, input, tokenCount, config, random, dependencies.createId);
@@ -183075,10 +183117,21 @@ function advanceLocationUnlock(stores, trainer, tokenCount, config, completedAt,
183075
183117
  return;
183076
183118
  const currentTokens = stores.exploration.unlockTokenCount(trainer.id);
183077
183119
  const next = nextLocation(trainer.regionId, trainer.locationId);
183120
+ const index = locationIndexFor(trainer.regionId, trainer.locationId);
183121
+ const championIndex = championIndexForRegion(trainer.regionId);
183122
+ const threshold = index === null || championIndex === null ? config.locationUnlockBaseTokens : locationUnlockThreshold({
183123
+ index,
183124
+ championIndex,
183125
+ curve: {
183126
+ baseTokens: config.locationUnlockBaseTokens,
183127
+ exponent: config.locationUnlockExponent,
183128
+ regionExponent: config.locationUnlockRegionExponent
183129
+ }
183130
+ });
183078
183131
  const result = calculateUnlockProgress({
183079
183132
  currentTokens,
183080
183133
  gainedTokens: tokenCount,
183081
- threshold: config.locationUnlockTokens,
183134
+ threshold,
183082
183135
  hasNextLocation: next !== null,
183083
183136
  currentLocationIsLatestUnlocked: true
183084
183137
  });
@@ -183178,7 +183231,11 @@ function randomInterval(config, random) {
183178
183231
  // src/application/game.ts
183179
183232
  function createApplicationGame(dependencies) {
183180
183233
  const { repository, random, now, config, createId, createStarterIds } = dependencies;
183181
- const readState = () => repository.readState(config.locationUnlockTokens);
183234
+ const readState = () => repository.readState({
183235
+ baseTokens: config.locationUnlockBaseTokens,
183236
+ exponent: config.locationUnlockExponent,
183237
+ regionExponent: config.locationUnlockRegionExponent
183238
+ });
183182
183239
  const commands = createGameCommands({
183183
183240
  transactions: repository.transactions,
183184
183241
  readState,
package/dist/rpc.js CHANGED
@@ -130,6 +130,11 @@ var explorationStatusSchema = z4.object({
130
130
  locationUnlockThreshold: z4.number().int().positive(),
131
131
  regionComplete: z4.boolean()
132
132
  });
133
+ function locationUnlockThreshold(input) {
134
+ const capped = Math.min(Math.max(input.index, 0), input.championIndex);
135
+ const cumulative = (i) => input.curve.baseTokens * (i + 1) ** input.curve.exponent * (input.championIndex + 1) ** input.curve.regionExponent;
136
+ return Math.round(cumulative(capped + 1) - cumulative(capped));
137
+ }
133
138
  function calculateUnlockProgress(input) {
134
139
  if (!input.currentLocationIsLatestUnlocked)
135
140
  return { kind: "not-latest" };
@@ -224,10 +229,11 @@ var starterChoiceResultSchema = z8.object({
224
229
  });
225
230
  var gameplayConfigSchema = z8.object({
226
231
  pauseOnPendingChoice: z8.boolean().default(true),
227
- xpTokensPerPoint: z8.number().int().positive().default(1000),
228
232
  encounterMinimumTokens: z8.number().int().positive().default(200000),
229
233
  encounterMaximumTokens: z8.number().int().positive().default(400000),
230
- locationUnlockTokens: z8.number().int().positive().default(2160000)
234
+ locationUnlockBaseTokens: z8.number().int().positive().default(4214000),
235
+ locationUnlockExponent: z8.number().positive().default(2.64),
236
+ locationUnlockRegionExponent: z8.number().default(-1.72)
231
237
  });
232
238
  var usageInputSchema = z8.object({
233
239
  sessionId: z8.string().min(1),