@nekosuneprojects/gaming-infos 2.2.0 → 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 (277) hide show
  1. package/CHANGELOG.md +77 -3
  2. package/README.md +62 -495
  3. package/index.js +3 -223
  4. package/package.json +53 -46
  5. package/src/providers/vrchat.js +11 -0
  6. package/src/providers/warframe.js +7 -0
  7. package/src/registry.js +23 -0
  8. package/.github/workflows/npm-publish-github-packages.yml +0 -56
  9. package/.github/workflows/npm-publish.yml +0 -71
  10. package/.github/workflows/sync-api-cache.yml +0 -72
  11. package/CACHE_SYNC.md +0 -172
  12. package/CONTRIBUTING.md +0 -217
  13. package/DATA.md +0 -292
  14. package/data/arknightsendfield/meta.json +0 -14
  15. package/data/fortnite/meta.json +0 -14
  16. package/data/game-codes/.gitkeep +0 -0
  17. package/data/genshinimpact/characters/albedo.json +0 -11
  18. package/data/genshinimpact/characters/alhaitham.json +0 -12
  19. package/data/genshinimpact/characters/aloy.json +0 -11
  20. package/data/genshinimpact/characters/amber.json +0 -12
  21. package/data/genshinimpact/characters/aratakiitto.json +0 -12
  22. package/data/genshinimpact/characters/arlecchino.json +0 -12
  23. package/data/genshinimpact/characters/baizhu.json +0 -12
  24. package/data/genshinimpact/characters/barbara.json +0 -11
  25. package/data/genshinimpact/characters/beidou.json +0 -12
  26. package/data/genshinimpact/characters/bennett.json +0 -11
  27. package/data/genshinimpact/characters/candace.json +0 -12
  28. package/data/genshinimpact/characters/charlotte.json +0 -11
  29. package/data/genshinimpact/characters/chasca.json +0 -11
  30. package/data/genshinimpact/characters/chevreuse.json +0 -11
  31. package/data/genshinimpact/characters/chiori.json +0 -11
  32. package/data/genshinimpact/characters/chongyun.json +0 -12
  33. package/data/genshinimpact/characters/citlali.json +0 -11
  34. package/data/genshinimpact/characters/clorinde.json +0 -11
  35. package/data/genshinimpact/characters/collei.json +0 -12
  36. package/data/genshinimpact/characters/cyno.json +0 -12
  37. package/data/genshinimpact/characters/dahlia.json +0 -10
  38. package/data/genshinimpact/characters/dehya.json +0 -11
  39. package/data/genshinimpact/characters/diluc.json +0 -11
  40. package/data/genshinimpact/characters/diona.json +0 -11
  41. package/data/genshinimpact/characters/dori.json +0 -11
  42. package/data/genshinimpact/characters/durin.json +0 -11
  43. package/data/genshinimpact/characters/emilie.json +0 -11
  44. package/data/genshinimpact/characters/escoffier.json +0 -12
  45. package/data/genshinimpact/characters/eula.json +0 -11
  46. package/data/genshinimpact/characters/faruzan.json +0 -12
  47. package/data/genshinimpact/characters/fischl.json +0 -12
  48. package/data/genshinimpact/characters/freminet.json +0 -11
  49. package/data/genshinimpact/characters/furina.json +0 -12
  50. package/data/genshinimpact/characters/gaming.json +0 -11
  51. package/data/genshinimpact/characters/ganyu.json +0 -11
  52. package/data/genshinimpact/characters/gorou.json +0 -12
  53. package/data/genshinimpact/characters/hutao.json +0 -12
  54. package/data/genshinimpact/characters/iansan.json +0 -11
  55. package/data/genshinimpact/characters/ineffa.json +0 -11
  56. package/data/genshinimpact/characters/jean.json +0 -11
  57. package/data/genshinimpact/characters/kachina.json +0 -11
  58. package/data/genshinimpact/characters/kaedeharakazuha.json +0 -12
  59. package/data/genshinimpact/characters/kaeya.json +0 -11
  60. package/data/genshinimpact/characters/kamisatoayaka.json +0 -11
  61. package/data/genshinimpact/characters/kamisatoayato.json +0 -11
  62. package/data/genshinimpact/characters/kaveh.json +0 -12
  63. package/data/genshinimpact/characters/keqing.json +0 -11
  64. package/data/genshinimpact/characters/kinich.json +0 -11
  65. package/data/genshinimpact/characters/kirara.json +0 -11
  66. package/data/genshinimpact/characters/klee.json +0 -11
  67. package/data/genshinimpact/characters/kujousara.json +0 -11
  68. package/data/genshinimpact/characters/kukishinobu.json +0 -12
  69. package/data/genshinimpact/characters/lanyan.json +0 -11
  70. package/data/genshinimpact/characters/layla.json +0 -11
  71. package/data/genshinimpact/characters/lisa.json +0 -12
  72. package/data/genshinimpact/characters/lohen.json +0 -11
  73. package/data/genshinimpact/characters/lynette.json +0 -11
  74. package/data/genshinimpact/characters/lyney.json +0 -11
  75. package/data/genshinimpact/characters/mavuika.json +0 -11
  76. package/data/genshinimpact/characters/mikaschmidt.json +0 -11
  77. package/data/genshinimpact/characters/mona.json +0 -12
  78. package/data/genshinimpact/characters/mualani.json +0 -11
  79. package/data/genshinimpact/characters/nahida.json +0 -12
  80. package/data/genshinimpact/characters/navia.json +0 -11
  81. package/data/genshinimpact/characters/neuvillette.json +0 -11
  82. package/data/genshinimpact/characters/nilou.json +0 -11
  83. package/data/genshinimpact/characters/ningguang.json +0 -11
  84. package/data/genshinimpact/characters/noelle.json +0 -12
  85. package/data/genshinimpact/characters/ororon.json +0 -11
  86. package/data/genshinimpact/characters/prune.json +0 -10
  87. package/data/genshinimpact/characters/qiqi.json +0 -12
  88. package/data/genshinimpact/characters/raidenshogun.json +0 -12
  89. package/data/genshinimpact/characters/razor.json +0 -11
  90. package/data/genshinimpact/characters/rosaria.json +0 -12
  91. package/data/genshinimpact/characters/sangonomiyakokomi.json +0 -12
  92. package/data/genshinimpact/characters/sayu.json +0 -11
  93. package/data/genshinimpact/characters/sethos.json +0 -11
  94. package/data/genshinimpact/characters/shenhe.json +0 -12
  95. package/data/genshinimpact/characters/shikanoinheizou.json +0 -12
  96. package/data/genshinimpact/characters/sigewinne.json +0 -11
  97. package/data/genshinimpact/characters/skirk.json +0 -11
  98. package/data/genshinimpact/characters/sucrose.json +0 -12
  99. package/data/genshinimpact/characters/thoma.json +0 -11
  100. package/data/genshinimpact/characters/tighnari.json +0 -12
  101. package/data/genshinimpact/characters/varesa.json +0 -11
  102. package/data/genshinimpact/characters/varka.json +0 -10
  103. package/data/genshinimpact/characters/venti.json +0 -12
  104. package/data/genshinimpact/characters/wanderer.json +0 -11
  105. package/data/genshinimpact/characters/wriothesley.json +0 -12
  106. package/data/genshinimpact/characters/xiangling.json +0 -12
  107. package/data/genshinimpact/characters/xianyun.json +0 -11
  108. package/data/genshinimpact/characters/xiao.json +0 -11
  109. package/data/genshinimpact/characters/xilonen.json +0 -11
  110. package/data/genshinimpact/characters/xingqiu.json +0 -12
  111. package/data/genshinimpact/characters/xinyan.json +0 -12
  112. package/data/genshinimpact/characters/yaemiko.json +0 -12
  113. package/data/genshinimpact/characters/yanfei.json +0 -12
  114. package/data/genshinimpact/characters/yaoyao.json +0 -12
  115. package/data/genshinimpact/characters/yelan.json +0 -11
  116. package/data/genshinimpact/characters/yoimiya.json +0 -12
  117. package/data/genshinimpact/characters/yumemizukimizuki.json +0 -11
  118. package/data/genshinimpact/characters/yunjin.json +0 -11
  119. package/data/genshinimpact/characters/zhongli.json +0 -11
  120. package/data/genshinimpact/characters/zibai.json +0 -11
  121. package/data/genshinimpact/meta.json +0 -14
  122. package/data/honkaistarrail/characters/acheron.json +0 -12
  123. package/data/honkaistarrail/characters/aglaea.json +0 -12
  124. package/data/honkaistarrail/characters/anaxa.json +0 -12
  125. package/data/honkaistarrail/characters/argenti.json +0 -12
  126. package/data/honkaistarrail/characters/arlan.json +0 -12
  127. package/data/honkaistarrail/characters/ashveil.json +0 -12
  128. package/data/honkaistarrail/characters/asta.json +0 -12
  129. package/data/honkaistarrail/characters/aventurine.json +0 -12
  130. package/data/honkaistarrail/characters/bailu.json +0 -12
  131. package/data/honkaistarrail/characters/blackswan.json +0 -12
  132. package/data/honkaistarrail/characters/blade.json +0 -12
  133. package/data/honkaistarrail/characters/boothill.json +0 -12
  134. package/data/honkaistarrail/characters/bronya.json +0 -12
  135. package/data/honkaistarrail/characters/castorice.json +0 -12
  136. package/data/honkaistarrail/characters/cerydra.json +0 -12
  137. package/data/honkaistarrail/characters/cipher.json +0 -12
  138. package/data/honkaistarrail/characters/clara.json +0 -12
  139. package/data/honkaistarrail/characters/constance.json +0 -12
  140. package/data/honkaistarrail/characters/cyrene.json +0 -12
  141. package/data/honkaistarrail/characters/danheng.json +0 -12
  142. package/data/honkaistarrail/characters/drratio.json +0 -12
  143. package/data/honkaistarrail/characters/feixiao.json +0 -12
  144. package/data/honkaistarrail/characters/firefly.json +0 -12
  145. package/data/honkaistarrail/characters/fuxuan.json +0 -12
  146. package/data/honkaistarrail/characters/gallagher.json +0 -12
  147. package/data/honkaistarrail/characters/gepard.json +0 -12
  148. package/data/honkaistarrail/characters/guinaifen.json +0 -12
  149. package/data/honkaistarrail/characters/hanya.json +0 -12
  150. package/data/honkaistarrail/characters/herta.json +0 -12
  151. package/data/honkaistarrail/characters/himeko.json +0 -13
  152. package/data/honkaistarrail/characters/hook.json +0 -12
  153. package/data/honkaistarrail/characters/huohuo.json +0 -12
  154. package/data/honkaistarrail/characters/hyacine.json +0 -12
  155. package/data/honkaistarrail/characters/hysilens.json +0 -12
  156. package/data/honkaistarrail/characters/jade.json +0 -12
  157. package/data/honkaistarrail/characters/jiaoqiu.json +0 -12
  158. package/data/honkaistarrail/characters/jingliu.json +0 -12
  159. package/data/honkaistarrail/characters/jingyuan.json +0 -12
  160. package/data/honkaistarrail/characters/kafka.json +0 -12
  161. package/data/honkaistarrail/characters/lingsha.json +0 -12
  162. package/data/honkaistarrail/characters/lisushang.json +0 -12
  163. package/data/honkaistarrail/characters/luka.json +0 -12
  164. package/data/honkaistarrail/characters/luocha.json +0 -12
  165. package/data/honkaistarrail/characters/lynx.json +0 -12
  166. package/data/honkaistarrail/characters/march7th.json +0 -12
  167. package/data/honkaistarrail/characters/misha.json +0 -12
  168. package/data/honkaistarrail/characters/moze.json +0 -12
  169. package/data/honkaistarrail/characters/mydei.json +0 -12
  170. package/data/honkaistarrail/characters/natasha.json +0 -12
  171. package/data/honkaistarrail/characters/pela.json +0 -12
  172. package/data/honkaistarrail/characters/phainon.json +0 -12
  173. package/data/honkaistarrail/characters/qingque.json +0 -12
  174. package/data/honkaistarrail/characters/rappa.json +0 -12
  175. package/data/honkaistarrail/characters/robin.json +0 -12
  176. package/data/honkaistarrail/characters/ruanmei.json +0 -12
  177. package/data/honkaistarrail/characters/sampo.json +0 -12
  178. package/data/honkaistarrail/characters/seele.json +0 -12
  179. package/data/honkaistarrail/characters/serval.json +0 -12
  180. package/data/honkaistarrail/characters/silverwolf.json +0 -12
  181. package/data/honkaistarrail/characters/sparkle.json +0 -12
  182. package/data/honkaistarrail/characters/tingyun.json +0 -12
  183. package/data/honkaistarrail/characters/topaz.json +0 -12
  184. package/data/honkaistarrail/characters/tribbie.json +0 -12
  185. package/data/honkaistarrail/characters/weltyang.json +0 -12
  186. package/data/honkaistarrail/characters/xueyi.json +0 -12
  187. package/data/honkaistarrail/characters/yanqing.json +0 -12
  188. package/data/honkaistarrail/characters/yaoguang.json +0 -12
  189. package/data/honkaistarrail/characters/yukong.json +0 -12
  190. package/data/honkaistarrail/characters/yunli.json +0 -12
  191. package/data/honkaistarrail/meta.json +0 -14
  192. package/data/nte/characters/adler.json +0 -14
  193. package/data/nte/characters/aurelia.json +0 -14
  194. package/data/nte/characters/baicang.json +0 -14
  195. package/data/nte/characters/chaos.json +0 -14
  196. package/data/nte/characters/chiz.json +0 -14
  197. package/data/nte/characters/daffodill.json +0 -14
  198. package/data/nte/characters/edgar.json +0 -14
  199. package/data/nte/characters/esperzero.json +0 -14
  200. package/data/nte/characters/fadia.json +0 -14
  201. package/data/nte/characters/haniel.json +0 -14
  202. package/data/nte/characters/hathor.json +0 -14
  203. package/data/nte/characters/hotori.json +0 -14
  204. package/data/nte/characters/iroi.json +0 -14
  205. package/data/nte/characters/jiuyuan.json +0 -14
  206. package/data/nte/characters/lacrimosa.json +0 -14
  207. package/data/nte/characters/mint.json +0 -14
  208. package/data/nte/characters/nanally.json +0 -14
  209. package/data/nte/characters/sakiri.json +0 -14
  210. package/data/nte/characters/shinku.json +0 -14
  211. package/data/nte/characters/skia.json +0 -14
  212. package/data/nte/meta.json +0 -14
  213. package/data/toweroffantasy/meta.json +0 -14
  214. package/data/vrchat/avatars/.gitkeep +0 -0
  215. package/data/vrchat/groups/clubzodiac.json +0 -7
  216. package/data/vrchat/groups/dirtydancers.json +0 -7
  217. package/data/vrchat/groups/drumsynews.json +0 -7
  218. package/data/vrchat/groups/ebola20.json +0 -7
  219. package/data/vrchat/groups/internationaldancersassociation.json +0 -7
  220. package/data/vrchat/groups/kannagang.json +0 -6
  221. package/data/vrchat/groups/lolisquad.json +0 -7
  222. package/data/vrchat/groups/nekonightsnightclub.json +0 -7
  223. package/data/vrchat/groups/nekostudios.json +0 -7
  224. package/data/vrchat/groups/nekosunecommunity.json +0 -7
  225. package/data/vrchat/groups/voidclub.json +0 -7
  226. package/data/vrchat/groups/voltdanceclub.json +0 -7
  227. package/data/vrchat/groups/vrceventsgroup.json +0 -7
  228. package/data/vrchat/groups/vrchatcommunitydiscord.json +0 -6
  229. package/data/vrchat/meta.json +0 -13
  230. package/data/vrchat/players/alto.json +0 -9
  231. package/data/vrchat/players/arcadum.json +0 -10
  232. package/data/vrchat/players/chairhandler.json +0 -9
  233. package/data/vrchat/players/chipz.json +0 -9
  234. package/data/vrchat/players/hikarivr.json +0 -10
  235. package/data/vrchat/players/kimple.json +0 -10
  236. package/data/vrchat/players/linkzr.json +0 -8
  237. package/data/vrchat/players/nagzz21.json +0 -9
  238. package/data/vrchat/players/nebride.json +0 -10
  239. package/data/vrchat/players/nekosunevr.json +0 -10
  240. package/data/vrchat/players/pokelawls.json +0 -9
  241. package/data/vrchat/players/qwonk.json +0 -8
  242. package/data/vrchat/players/roflgator.json +0 -10
  243. package/data/vrchat/players/scifri.json +0 -7
  244. package/data/vrchat/players/sodapoppin.json +0 -9
  245. package/data/vrchat/players/woops.json +0 -9
  246. package/data/vrchat/players/zentreya.json +0 -10
  247. package/data/vrchat/worlds/ascensionacademy.json +0 -7
  248. package/data/vrchat/worlds/clubvgl.json +0 -8
  249. package/data/vrchat/worlds/fightfinder.json +0 -8
  250. package/data/vrchat/worlds/hangouthouse.json +0 -7
  251. package/data/vrchat/worlds/nekostudioshalloween.json +0 -9
  252. package/data/vrchat/worlds/nekostudiosnewyear.json +0 -9
  253. package/data/vrchat/worlds/nekostudiosxmas.json +0 -9
  254. package/data/vrchat/worlds/nekosunevranimations2023.json +0 -9
  255. package/data/vrchat/worlds/nekosunevranimations2024.json +0 -9
  256. package/data/vrchat/worlds/nekosunevranimations2025.json +0 -9
  257. package/data/vrchat/worlds/rumhamsavatarworld.json +0 -7
  258. package/data/vrchat/worlds/smewsranch.json +0 -7
  259. package/data/vrchat/worlds/smewsroom.json +0 -7
  260. package/data/vrchat/worlds/sunsetbar.json +0 -7
  261. package/data/vrchat/worlds/theblackcat.json +0 -9
  262. package/data/vrchat/worlds/thegreatpug.json +0 -8
  263. package/data/vrchat/worlds/themidnightbar.json +0 -7
  264. package/data/vrchat/worlds/voidclub.json +0 -7
  265. package/data/vrchat/worlds/voltdanceclub.json +0 -7
  266. package/data/vrchat/worlds/vrchathome.json +0 -8
  267. package/data/vrchat/worlds/whatalegend.json +0 -6
  268. package/data/warframe/meta.json +0 -14
  269. package/data/wutheringwaves/meta.json +0 -14
  270. package/data/zenlesszonezero/meta.json +0 -14
  271. package/gamecodes.js +0 -178
  272. package/scripts/cache-sync-smoke.js +0 -92
  273. package/scripts/game-code-cache-smoke.js +0 -85
  274. package/scripts/sync-all-cache.js +0 -18
  275. package/scripts/sync-api-cache.js +0 -319
  276. package/scripts/sync-game-code-cache.js +0 -244
  277. package/scripts/sync-gaming-info-cache.js +0 -46
package/CACHE_SYNC.md DELETED
@@ -1,172 +0,0 @@
1
- # APINODE fallback-cache mirror
2
-
3
- `@nekosuneprojects/gaming-infos` is API-first. Normal reads try the NekoSuneVR V5 API before using bundled JSON under `data/`.
4
-
5
- The repository keeps **two independent last-good fallback snapshots** synchronized automatically:
6
-
7
- - Gaming Infos: `GET /v5/games/api/gaming-infos`
8
- - Game Codes: `GET /v5/games/api/codes`
9
-
10
- ## Schedule
11
-
12
- The GitHub Action runs **once every day at 03:23 UTC** and can also be started manually with `workflow_dispatch`.
13
-
14
- It also runs when the cache implementation itself changes so a newly deployed cache format can be populated immediately.
15
-
16
- ## Mirrored gaming-infos datasets
17
-
18
- | Game | API type(s) |
19
- |---|---|
20
- | VRChat | `players`, `groups`, `worlds`, `avatars` |
21
- | Genshin Impact | `characters` |
22
- | Honkai: Star Rail | `characters` |
23
- | Neverness to Everness | `characters` |
24
- | Wuthering Waves | `characters` (Resonators) |
25
- | Warframe | `characters` (Warframes) |
26
- | Fortnite | `characters` (current/released Battle Royale characters) |
27
- | Zenless Zone Zero | `characters` (Agents) |
28
- | Tower of Fantasy | `characters` (Simulacra) |
29
- | Arknights: Endfield | `characters` (Operators) |
30
-
31
- ## Mirrored Game Codes endpoints
32
-
33
- The daily mirror also caches:
34
-
35
- ```text
36
- GET /v5/games/api/codes
37
- GET /v5/games/api/codes/status
38
- GET /v5/games/api/codes/:game?includeUnknown=true
39
- ```
40
-
41
- `/codes/status` only reads APINODE's cached source state. It does **not** trigger source website refreshes.
42
-
43
- The per-game request uses `includeUnknown=true`, so the fallback contains all three buckets when available:
44
-
45
- ```json
46
- {
47
- "Active": [],
48
- "Expired": [],
49
- "Unknown": []
50
- }
51
- ```
52
-
53
- The mirror does not call every `/:game/:code` endpoint. `GameCode(game, code)` can search the full cached per-game snapshot during an outage, which keeps the daily request count low.
54
-
55
- Game-code fallback layout:
56
-
57
- ```text
58
- data/game-codes/
59
- ├── directory.json
60
- ├── status.json
61
- ├── .cache-manifest.json
62
- └── games/
63
- ├── fortnite.json
64
- ├── warframe.json
65
- ├── genshin-impact.json
66
- └── ...
67
- ```
68
-
69
- ## Atomic synchronization / deletion behavior
70
-
71
- Each cache is authoritative only **after its complete API download succeeds**.
72
-
73
- For Gaming Infos:
74
-
75
- 1. Temporarily preserve `data/game-codes/` outside the gaming-info snapshot.
76
- 2. Fetch the root gaming-infos endpoint.
77
- 3. Fetch every configured game's meta endpoint.
78
- 4. Fetch every configured type-list endpoint.
79
- 5. Validate every response and entry slug.
80
- 6. Build a completely separate temporary snapshot.
81
- 7. Atomically replace the gaming-info `data/` snapshot.
82
- 8. Restore the previous game-code fallback before the code phase begins.
83
-
84
- For Game Codes:
85
-
86
- 1. Fetch `/codes` and validate its game directory.
87
- 2. Fetch cache-only `/codes/status`.
88
- 3. Fetch every listed game's full `Active` / `Expired` / `Unknown` snapshot.
89
- 4. Build a separate temporary `data/game-codes/` tree.
90
- 5. Only after every game succeeds, atomically replace the old game-code snapshot.
91
-
92
- Because successful API snapshots are authoritative, **adds, changes and removals are mirrored**. If APINODE removes an entry/code/game, the corresponding fallback disappears on the next successful daily sync.
93
-
94
- If APINODE is down, times out, returns 429/5xx, or one required endpoint fails halfway through, that cache is **not replaced**. The previous last-good fallback remains available.
95
-
96
- ## Package API
97
-
98
- Gaming Infos functions remain available:
99
-
100
- ```js
101
- const info = require('@nekosuneprojects/gaming-infos');
102
-
103
- await info.Games();
104
- await info.List('vrchat', 'avatars');
105
- await info.Characters('wutheringwaves', 'cartethyia');
106
- ```
107
-
108
- Game Codes helpers use live APINODE first and the daily fallback second:
109
-
110
- ```js
111
- await info.Codes(); // GET /v5/games/api/codes
112
- await info.CodesStatus(); // GET /v5/games/api/codes/status
113
- await info.GameCodes('fortnite'); // Active + Expired
114
- await info.GameCodes('fortnite', { includeUnknown: true });
115
- await info.GameCode('fortnite', 'NEKOSUNEVR');
116
- await info.CodeCacheInfo();
117
- ```
118
-
119
- Per-game fallback filtering is supported for `category` and `claimType` as well.
120
-
121
- ## Commands
122
-
123
- ```bash
124
- # Test both atomic cache systems
125
- npm run test:all-cache
126
-
127
- # Mirror both Gaming Infos and Game Codes
128
- npm run sync:cache
129
-
130
- # Debug individually
131
- npm run sync:gaming-infos-cache
132
- npm run sync:game-codes-cache
133
- npm run test:cache-sync
134
- npm run test:game-code-cache
135
- ```
136
-
137
- Override APINODE while testing:
138
-
139
- ```bash
140
- GAMING_INFOS_API_BASE=http://localhost:3000 npm run sync:cache
141
- ```
142
-
143
- Useful variables:
144
-
145
- | Variable | Default | Purpose |
146
- |---|---|---|
147
- | `GAMING_INFOS_API_BASE` | `https://api.nekosunevr.co.uk` | APINODE host used by both caches |
148
- | `GAMING_INFOS_API_PATH` | `/v5/games/api/gaming-infos` | Gaming Infos path |
149
- | `GAME_CODES_API_PATH` | `/v5/games/api/codes` | Game Codes path |
150
- | `GAMING_INFOS_CACHE_TIMEOUT_MS` | `15000` | Gaming Infos per-request timeout |
151
- | `GAMING_INFOS_CACHE_RETRIES` | `2` | Gaming Infos retry count |
152
- | `GAME_CODES_CACHE_TIMEOUT_MS` | `15000` | Game Codes per-request timeout |
153
- | `GAME_CODES_CACHE_RETRIES` | `2` | Game Codes retry count |
154
- | `GAME_CODES_CACHE_GAME_DELAY_MS` | `150` | Small delay between game-list requests |
155
-
156
- ## Runtime fallback behavior
157
-
158
- The package does **not** use the cache instead of live data. It remains API-first:
159
-
160
- ```text
161
- application
162
- ↓
163
- live APINODE
164
- ├─ success → current API response
165
- └─ unavailable/error → last-good bundled fallback
166
- ```
167
-
168
- A successful changed Gaming Infos snapshot records `data/.cache-manifest.json`. Game Codes records its own `data/game-codes/.cache-manifest.json`. Both include source URL, content hash, counts, synchronization time and add/change/remove statistics.
169
-
170
- The hash comparison ignores manifest timestamps, so an unchanged API dataset does not create a pointless daily commit.
171
-
172
- Note: npm releases are immutable. Repository fallback files update daily, but an already-installed npm version keeps the bundled snapshot from that package release until upgraded. Live API reads still remain current whenever APINODE is available.
package/CONTRIBUTING.md DELETED
@@ -1,217 +0,0 @@
1
- # 🤝 Contributing to @nekosuneprojects/gaming-infos
2
-
3
- Thank you for your interest in contributing to **@nekosuneprojects/gaming-infos**!
4
- This project relies on community help to keep game data organized, accurate, and friendly — across every game it covers,
5
- not just VRChat.
6
-
7
- Please read this guide carefully **before submitting a Pull Request (PR)**.
8
-
9
- ---
10
-
11
- ## 🦊 Overview
12
-
13
- This project provides **community game info** — worlds, groups, players, characters, and more — in JSON format, used by
14
- scripts and tools. Data lives in the `data/` folder, scoped per game:
15
-
16
- ```
17
- data/
18
- └── <game>/
19
- ├── meta.json
20
- ├── worlds/
21
- ├── groups/
22
- ├── players/
23
- └── characters/
24
- ```
25
-
26
- Each JSON file represents a public piece of info about a world, group, player, or character for that game.
27
- Not every game uses every folder — e.g. VRChat uses `worlds`/`groups`/`players`, while a character-driven game like
28
- Genshin Impact mainly uses `characters`. Use the `Get(game, type, name)` function for any entity type a new game
29
- needs that isn't already listed above.
30
-
31
- ---
32
-
33
- ## ✅ Contribution Rules
34
-
35
- ### 1. Permission & Privacy
36
-
37
- - Only include **publicly available data** or **data you have explicit permission** to share.
38
- - If the data comes from **private profiles, Discord servers, or DMs**, **do not submit it**.
39
- - You must **ask permission** from the world/group/player/character owner if the information is not publicly listed.
40
- - Do **not** upload personal or sensitive details under any circumstance.
41
-
42
- ### 2. Accepted Public Sources
43
-
44
- You may use:
45
- - Official game wikis/fandoms (e.g. [VRChat Legends (Fandom)](https://vrchat-legends.fandom.com), official Genshin Impact wiki, etc.)
46
- - Official game pages, group listings, or public user profiles.
47
- - Other verified public sources (must be referenced in the PR description).
48
-
49
- If the source is not verifiable or permission is unclear, your PR will be closed.
50
-
51
- ---
52
-
53
- ## 🚫 Community & Safety Guidelines
54
-
55
- All contributions must comply with the relevant game's Terms of Service and Community Guidelines, e.g. for VRChat:
56
-
57
- - **VRChat's Terms of Service**:
58
- [https://hello.vrchat.com/legal](https://hello.vrchat.com/legal)
59
-
60
- - **VRChat's Community Guidelines**:
61
- [https://hello.vrchat.com/community-guidelines](https://hello.vrchat.com/community-guidelines)
62
-
63
- ### Forbidden Content:
64
- - Harassment, bullying, or targeted remarks.
65
- - Doxxing or sharing private user data.
66
- - Hate speech, NSFW content, or anything that violates a game's ToS or GitHub rules.
67
- - False, misleading, or defamatory information.
68
-
69
- Such PRs will be rejected and may result in a report to platform moderators.
70
-
71
- ---
72
-
73
- ## 🖼️ Image Requirement
74
-
75
- Every JSON file **must include an `image` field** linking to a **safe, representative image** (world thumbnail, group
76
- logo, avatar/character art).
77
-
78
- Example:
79
- ```json
80
- "image": "https://example.com/images/world.png"
81
- ```
82
-
83
- Images must not contain:
84
- - Private or copyrighted art without permission.
85
- - NSFW or offensive visuals.
86
-
87
- ---
88
-
89
- ## 🧩 JSON Format Guidelines
90
-
91
- Follow these formats exactly when adding files. New games should follow the same shape for whichever entity types
92
- apply to them.
93
-
94
- ### 🌍 Worlds (`data/<game>/worlds/worldname.json`)
95
- ```json
96
- {
97
- "name": "The Black Cat",
98
- "title": "Main Hall",
99
- "creator": "spookyghostboo",
100
- "aliases": "Black Cat",
101
- "image": "https://example.com/images/world.jpg",
102
- "description": "A cozy hangout world for friends.",
103
- "url": "VRCHAT WORLD URL"
104
- }
105
- ```
106
-
107
- ### 👥 Groups (`data/<game>/groups/groupname.json`)
108
- ```json
109
- {
110
- "name": "NekoSune Community",
111
- "owner": "NekoSuneVR",
112
- "image": "https://example.com/images/group.png",
113
- "description": "A friendly VRChat group for chill vibes and fun events.",
114
- "url": "VRCHAT GROUP URL"
115
- }
116
- ```
117
-
118
- ### 🧍 Players (`data/<game>/players/playername.json`)
119
- ```json
120
- {
121
- "name": "NekoSuneVR",
122
- "title": "The Cutie Streamer",
123
- "species": "half human - half catgirl",
124
- "gender": "Male",
125
- "aliases": "ChisdealHDYT, Chisdeal2013, Chisdeal2014, ChisdealHD, progamer-gr, DarkBlackWolfs",
126
- "image": "https://media.discordapp.net/attachments/794229972490387496/794231249652678696/VRChat_1920x1080_2020-09-14_09-22-18.855.png",
127
- "description": "A long time ago, Wild Player Chisdeal2013 (later known as ChisdealHDYT). He had been hanging out in a place called [The Black Cat](https://vrchat-legends.fandom.com/wiki/The_Black_Cat), [The Great Pug](https://vrchat-legends.fandom.com/wiki/The_Great_Pug) and [Japan Shrine (ITOAR)](https://vrchat-legends.fandom.com/wiki/Japan_Shrine_(ITOAR)). He had been talking about how he wanted to be Popular on [Twitch](https://twitch.tv/chisdealhdyt) and [TikTok](https://www.tiktok.com/@chisdealhd) / [YouTube](https://www.youtube.com/chisdealhd). Then he did started to streaming on Twitch and Upload Videos on TikTok / YouTube. He loves interest Cryptocurrency Money making and has lot support from [ZENZO Community](https://zenzo.io). He building Community with VRChat, Warframe and many more. He want become as VTuber as Twitch and doing a lot of VR Gaming. That dream is coming very soon in stage getting VR Headset and Brand new VR Ready PC.\n\nYou should Support this Cutie Streamer much on your Heart it can go.",
128
- "url": "https://creator.nekosunevr.co.uk"
129
- }
130
- ```
131
-
132
- ### 🧝 Characters (`data/<game>/characters/charactername.json`)
133
- ```json
134
- {
135
- "name": "Amber",
136
- "quote": "Outrider Amber, at the ready!",
137
- "cv": "Iwami Manaka",
138
- "description": "A perky, straightforward girl, who is also the only Outrider of the Knights of Favonius.",
139
- "image": "https://uploadstatic-sea.mihoyo.com/contentweb/20191009/2019100914372396510.png",
140
- "city": "Mondstadt",
141
- "url": "https://genshin.mihoyo.com/en/character/mondstadt?char=1",
142
- "element": "Pyro",
143
- "weapon": "Bow",
144
- "rating": 4
145
- }
146
- ```
147
- `element` stays a plain string (icon mapping is a consumer-side concern, not stored here).
148
- `rating` is the in-game star rarity (1-5) as a number. Include whatever fields apply to that
149
- game's characters (`cv`, `city`, etc.) and drop what doesn't.
150
-
151
- ### 🎮 Game meta (`data/<game>/meta.json`)
152
- ```json
153
- {
154
- "name": "Genshin Impact",
155
- "title": "An open-world action RPG developed by HoYoverse.",
156
- "engine": "Unity",
157
- "Platform": "PC, PlayStation, iOS, Android",
158
- "Release date": "September 28, 2020",
159
- "Genre": "Action RPG, Open World, Gacha",
160
- "developers": "HoYoverse",
161
- "aliases": "GI, Genshin",
162
- "image": "https://example.com/images/genshin-logo.png",
163
- "description": "Short factual description of the game.",
164
- "url": "https://en.wikipedia.org/wiki/Genshin_Impact"
165
- }
166
- ```
167
-
168
- ---
169
-
170
- ## 🪶 How to Submit a Pull Request
171
-
172
- 1. **Fork** this repository.
173
- 2. **Create a new branch** for your changes:
174
- ```bash
175
- git checkout -b add-new-world
176
- ```
177
- 3. Add or update JSON files under `data/<game>/...`. If adding a **new game**, create `data/<newgame>/meta.json`
178
- plus whichever entity folders apply (`worlds`, `groups`, `players`, `characters`, or a new type via `Get()`).
179
- 4. Ensure your files are valid JSON and properly formatted.
180
- 5. **Commit and push** your changes:
181
- ```bash
182
- git commit -m "Add Example World info"
183
- git push origin add-new-world
184
- ```
185
- 6. **Open a Pull Request** on GitHub with:
186
- - A clear title (e.g., "Add Genshin Impact character Furina")
187
- - A short explanation
188
- - Source links or permissions if applicable
189
-
190
- ---
191
-
192
- ## 🔍 Before Submitting
193
-
194
- ✅ Validate your JSON syntax using:
195
- ```bash
196
- npm run lint
197
- ```
198
- (if available) or an online JSON validator.
199
-
200
- ✅ Make sure:
201
- - You have **permission** to share the content.
202
- - The **image link** works and is safe.
203
- - The **file name matches the item name** (lowercase recommended).
204
- - The file is in the correct `data/<game>/<type>/` folder.
205
-
206
- ---
207
-
208
- ## 🧠 Final Notes
209
-
210
- - This project is **game-friendly** and follows all relevant ToS and Community Guidelines.
211
- - The maintainers reserve the right to remove or edit contributions that break policy.
212
- - All content remains under the [MIT License](LICENSE) unless otherwise noted.
213
-
214
- ---
215
-
216
- 🐾 Maintained by **NekoSune Projects**
217
- 💬 Community contributions are welcome — just keep it kind, safe, and respectful!
package/DATA.md DELETED
@@ -1,292 +0,0 @@
1
- # Gaming Infos — Data & API Spec
2
-
3
- > **Forward this file into `V5_REBUILD_GREEN`.** It's the shared spec between the
4
- > `@nekosuneprojects/gaming-infos` npm package and the V5 API. The npm package now calls the API
5
- > first for live data and only falls back to its own bundled JSON if the API is unreachable — so
6
- > once this is wired up here, the game/character list can be updated in real time by editing JSON
7
- > in this repo, without ever needing to bump the npm package version.
8
-
9
- ## What this covers
10
-
11
- Community info about games — worlds, groups, players, characters, and whatever else a future game
12
- needs — as small JSON files. Today: VRChat. Coming soon: Genshin Impact, and more. Each game only
13
- uses the entity types that make sense for it (VRChat: worlds/groups/players. A character-driven
14
- game like Genshin Impact: mostly characters.).
15
-
16
- This is **not** the same thing as the existing `src/routes/v5/games/*` routes (Destiny2, Fortnite,
17
- Hypixel, VRChat profile lookup, etc.) — those pull *live player/account stats* from third-party
18
- game APIs. `gaming-infos` is curated, hand-written community reference data (bios, lore, links),
19
- served as static JSON.
20
-
21
- ---
22
-
23
- ## 1. Where the JSON lives
24
-
25
- Create this folder structure under the API project root:
26
-
27
- ```
28
- V5_REBUILD_GREEN/
29
- └── data/
30
- └── gaming-infos/
31
- └── <game>/
32
- ├── meta.json
33
- ├── worlds/<name>.json
34
- ├── groups/<name>.json
35
- ├── players/<name>.json
36
- └── characters/<name>.json
37
- ```
38
-
39
- Rules:
40
- - `<game>` is lowercase, no spaces, e.g. `vrchat`, `genshinimpact`.
41
- - `<name>` (the filename, minus `.json`) is lowercase, no spaces, e.g. `theblackcat.json`, `furina.json`.
42
- - Only create the entity folders a game actually uses — don't create empty `worlds/` for a game with no worlds.
43
- - `meta.json` holds game-level info (see schema below) and is required for every game.
44
-
45
- This mirrors the npm package's own `data/<game>/...` layout 1:1, so JSON can be copied between the
46
- two repos without any transformation.
47
-
48
- ---
49
-
50
- ## 2. JSON schemas
51
-
52
- ### Game meta — `data/gaming-infos/<game>/meta.json`
53
- ```json
54
- {
55
- "name": "Genshin Impact",
56
- "title": "An open-world action RPG developed by HoYoverse.",
57
- "engine": "Unity",
58
- "Platform": "PC, PlayStation, iOS, Android",
59
- "Release date": "September 28, 2020",
60
- "Genre": "Action RPG, Open World, Gacha",
61
- "developers": "HoYoverse",
62
- "aliases": "GI, Genshin",
63
- "image": "https://example.com/images/genshin-logo.png",
64
- "description": "Short factual description of the game.",
65
- "url": "https://en.wikipedia.org/wiki/Genshin_Impact"
66
- }
67
- ```
68
-
69
- ### World — `data/gaming-infos/<game>/worlds/<name>.json`
70
- ```json
71
- {
72
- "name": "The Black Cat",
73
- "title": "Main Hall",
74
- "creator": "spookyghostboo",
75
- "aliases": "Black Cat",
76
- "image": "https://example.com/images/world.jpg",
77
- "description": "A cozy hangout world for friends.",
78
- "url": "VRCHAT WORLD URL"
79
- }
80
- ```
81
-
82
- ### Group — `data/gaming-infos/<game>/groups/<name>.json`
83
- ```json
84
- {
85
- "name": "NekoSune Community",
86
- "owner": "NekoSuneVR",
87
- "image": "https://example.com/images/group.png",
88
- "description": "A friendly VRChat group for chill vibes and fun events.",
89
- "url": "VRCHAT GROUP URL"
90
- }
91
- ```
92
-
93
- ### Player — `data/gaming-infos/<game>/players/<name>.json`
94
- ```json
95
- {
96
- "name": "NekoSuneVR",
97
- "title": "The Cutie Streamer",
98
- "species": "half human - half catgirl",
99
- "gender": "Male",
100
- "aliases": "ChisdealHDYT, Chisdeal2013",
101
- "image": "https://example.com/images/nekosunevr.png",
102
- "description": "Bio text, markdown links allowed.",
103
- "url": "https://creator.nekosunevr.co.uk"
104
- }
105
- ```
106
-
107
- ### Character — `data/gaming-infos/<game>/characters/<name>.json`
108
- ```json
109
- {
110
- "name": "Amber",
111
- "quote": "Outrider Amber, at the ready!",
112
- "cv": "Iwami Manaka",
113
- "description": "A perky, straightforward girl, who is also the only Outrider of the Knights of Favonius.",
114
- "image": "https://uploadstatic-sea.mihoyo.com/contentweb/20191009/2019100914372396510.png",
115
- "city": "Mondstadt",
116
- "url": "https://genshin.mihoyo.com/en/character/mondstadt?char=1",
117
- "element": "Pyro",
118
- "weapon": "Bow",
119
- "rating": 4
120
- }
121
- ```
122
- - `element` is a plain string (Pyro/Hydro/Electro/Cryo/Anemo/Geo/Dendro) — no icon URL stored here;
123
- element -> icon mapping is a consumer-side concern.
124
- - `rating` is the in-game star rarity (1-5) as a number.
125
- - `cv` (voice actor) and `city` are Genshin-specific; other character-driven games can drop/replace
126
- them with whatever fields fit (e.g. a fighting game might use `moveset` instead of `city`).
127
-
128
- Every entity JSON has an `image` field. When you have a verified, safe (non-NSFW, not privately
129
- owned without permission) working URL, use it. When you don't, leave it as an **empty string**
130
- (`"image": ""`) — never fill it with a placeholder/TODO string, since that gets treated as real
131
- data by consumers.
132
-
133
- If a game needs an entity type not listed above (e.g. `weapons`, `regions`, `guilds`), just add a
134
- new folder following the same `data/gaming-infos/<game>/<type>/<name>.json` pattern — the npm
135
- package's `Get(game, type, name)` function reads any type generically.
136
-
137
- ---
138
-
139
- ## 3. Sourcing & safety rules
140
-
141
- - Only use **publicly available** info, or info you have explicit permission to publish.
142
- - Never include data from private profiles, private Discords, or DMs.
143
- - No harassment, doxxing, defamation, or NSFW content.
144
- - Respect each game's Terms of Service / Community Guidelines (e.g. VRChat's
145
- [ToS](https://hello.vrchat.com/legal) and [Community Guidelines](https://hello.vrchat.com/community-guidelines)).
146
- - Prefer official wikis/fandoms and official game pages as sources; note the source in your PR/commit if unclear.
147
-
148
- ---
149
-
150
- ## 4. Wiring up the API route
151
-
152
- Follow the existing pattern used by every other file in `src/routes/v5/games/*`
153
- (`checkEndpointEnabled` + `requireApiKeyIfNeeded` middleware, mounted under `/v5/games/api/...`).
154
-
155
- There are four routes: list all games, list all entries of a type for a game, a single entity, and
156
- game meta (meta is just the single-entity route with `type` fixed to `meta`).
157
-
158
- 1. Create `src/routes/v5/games/gaminginfos.js`:
159
-
160
- ```js
161
- const express = require('express');
162
- const fs = require('fs');
163
- const path = require('path');
164
- const { checkEndpointEnabled, requireApiKeyIfNeeded } = require('../../../middleware/apiAccess');
165
-
166
- const router = express.Router({ strict: false });
167
- const DATA_DIR = path.join(__dirname, '..', '..', '..', '..', 'data', 'gaming-infos');
168
-
169
- function readJson(filePath) {
170
- return JSON.parse(fs.readFileSync(filePath, 'utf8'));
171
- }
172
-
173
- // GET /v5/games/api/gaming-infos — list every game's meta info
174
- router.get('/', checkEndpointEnabled, requireApiKeyIfNeeded, (req, res) => {
175
- try {
176
- const entries = fs.readdirSync(DATA_DIR, { withFileTypes: true }).filter((e) => e.isDirectory());
177
- const gamesList = entries
178
- .map((e) => path.join(DATA_DIR, e.name, 'meta.json'))
179
- .filter((metaPath) => fs.existsSync(metaPath))
180
- .map(readJson);
181
- return res.status(200).json({ success: true, data: gamesList });
182
- } catch (err) {
183
- return res.status(500).json({ success: false, error: 'Failed to list games.' });
184
- }
185
- });
186
-
187
- // GET /v5/games/api/gaming-infos/:game/:type — list every entry of that type for a game
188
- router.get('/:game/:type', checkEndpointEnabled, requireApiKeyIfNeeded, (req, res) => {
189
- const { game, type } = req.params;
190
- const dir = path.join(DATA_DIR, game.toLowerCase(), type.toLowerCase());
191
-
192
- if (!dir.startsWith(DATA_DIR) || !fs.existsSync(dir)) {
193
- return res.status(404).json({ success: false, error: `No ${type} data found for game "${game}"` });
194
- }
195
-
196
- try {
197
- const items = fs.readdirSync(dir).filter((f) => f.endsWith('.json')).map((f) => readJson(path.join(dir, f)));
198
- return res.status(200).json({ success: true, data: items });
199
- } catch (err) {
200
- return res.status(500).json({ success: false, error: 'Failed to list gaming-infos entries.' });
201
- }
202
- });
203
-
204
- // GET /v5/games/api/gaming-infos/:game/:type/:name — a single entity, or game meta when type === "meta"
205
- router.get('/:game/:type/:name', checkEndpointEnabled, requireApiKeyIfNeeded, (req, res) => {
206
- const { game, type, name } = req.params;
207
- const filePath = type.toLowerCase() === 'meta'
208
- ? path.join(DATA_DIR, game.toLowerCase(), 'meta.json')
209
- : path.join(DATA_DIR, game.toLowerCase(), type.toLowerCase(), `${name.toLowerCase()}.json`);
210
-
211
- if (!filePath.startsWith(DATA_DIR) || !fs.existsSync(filePath)) {
212
- return res.status(404).json({ success: false, error: `${type} "${name}" not found for game "${game}"` });
213
- }
214
-
215
- try {
216
- return res.status(200).json({ success: true, data: readJson(filePath) });
217
- } catch (err) {
218
- return res.status(500).json({ success: false, error: 'Failed to read gaming-infos data.' });
219
- }
220
- });
221
-
222
- module.exports = router;
223
- ```
224
-
225
- 2. Register it in `src/app.js` next to the other game routes:
226
-
227
- ```js
228
- const gamingInfosRoutes = require('./routes/v5/games/gaminginfos');
229
- // ...
230
- app.use('/v5/games/api/gaming-infos', gamingInfosRoutes);
231
- ```
232
-
233
- 3. Add the endpoint(s) to `DEFAULT_ENDPOINTS` in `src/services/bootstrap.js` so
234
- `checkEndpointEnabled` accepts them (same convention as every other `games/api/*` entry):
235
-
236
- ```js
237
- {
238
- path: '/v5/games/api/gaming-infos',
239
- method: 'GET',
240
- isEnabled: true,
241
- requiresApiKey: false,
242
- description: 'List every game with gaming-infos data'
243
- },
244
- {
245
- path: '/v5/games/api/gaming-infos/:game/:type',
246
- method: 'GET',
247
- isEnabled: true,
248
- requiresApiKey: false,
249
- description: 'List every gaming-infos entry of a type for a game'
250
- },
251
- {
252
- path: '/v5/games/api/gaming-infos/:game/:type/:name',
253
- method: 'GET',
254
- isEnabled: true,
255
- requiresApiKey: false,
256
- description: 'Community gaming-infos single-entity lookup (worlds/groups/players/characters/meta/etc.)'
257
- },
258
- ```
259
-
260
- `bootstrapData()` (called on every app startup in `src/app.js`) runs `seedEndpoints()`, which
261
- `findOrCreate`s each `DEFAULT_ENDPOINTS` row into the `EndpointToggle` table — so these three
262
- entries go live (and show up on `/docs` automatically, since that page renders straight from
263
- `EndpointToggle`) the next time the server restarts. No manual DB or docs-page edit needed.
264
-
265
- The npm package expects responses shaped as `{ success: true, data: {...} }` (or a bare JSON object/array —
266
- it accepts either) and defaults to `https://api.nekosunevr.co.uk/v5/games/api/gaming-infos` as the
267
- base URL. If the real public host differs, override it per-consumer via the `GAMING_INFOS_API_BASE`
268
- env var — nothing here needs to change either way. The npm package's `Games()` calls the root route,
269
- `List(game, type)` calls the two-segment route, and everything else calls the three-segment route.
270
-
271
- ---
272
-
273
- ## 5. Prompt template — adding/updating a game or entry
274
-
275
- Copy-paste this (filling in the brackets) when asking an AI assistant to add or refresh gaming-infos
276
- data in this repo:
277
-
278
- ```
279
- Add/update gaming-infos data in this repo (data/gaming-infos/), following DATA.md:
280
-
281
- - Game: <e.g. Genshin Impact>
282
- - Entity type: <world|group|player|character|other>
283
- - Name(s): <e.g. Furina, Nahida>
284
- - Source(s): <official wiki/page URL(s) — public only, no private info>
285
-
286
- Look up current, accurate public info for each name above, write one JSON file per entry at
287
- data/gaming-infos/<game>/<type>/<lowercase-name>.json matching the schema in DATA.md section 2
288
- (include a working, safe image URL), and create/update data/gaming-infos/<game>/meta.json if this
289
- is a new game. Don't touch the API route code unless it doesn't exist yet for this game group —
290
- DATA.md section 4 has the route setup if needed. Skip anything that isn't publicly sourced or
291
- permissioned.
292
- ```