gotchi-battler-game-logic 3.0.0 → 4.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 (61) hide show
  1. package/.cursor/rules/cursor-rules.mdc +67 -0
  2. package/.cursor/rules/directory-structure.mdc +63 -0
  3. package/.cursor/rules/self-improvement.mdc +64 -0
  4. package/.cursor/rules/tech-stack.mdc +99 -0
  5. package/README.md +4 -0
  6. package/eslint.config.js +31 -0
  7. package/game-logic/index.js +2 -6
  8. package/game-logic/v1.4/constants.js +0 -23
  9. package/game-logic/v1.4/index.js +64 -56
  10. package/game-logic/v1.5/constants.js +0 -23
  11. package/game-logic/v1.5/index.js +27 -21
  12. package/game-logic/v1.6/constants.js +0 -23
  13. package/game-logic/v1.6/index.js +27 -21
  14. package/game-logic/v1.7/constants.js +0 -23
  15. package/game-logic/v1.7/helpers.js +2 -2
  16. package/game-logic/v1.7/index.js +24 -18
  17. package/game-logic/v1.8/constants.js +0 -23
  18. package/game-logic/v1.8/helpers.js +2 -2
  19. package/game-logic/v1.8/index.js +25 -19
  20. package/game-logic/v2.0/constants.js +112 -0
  21. package/game-logic/v2.0/helpers.js +713 -0
  22. package/game-logic/v2.0/index.js +782 -0
  23. package/game-logic/v2.0/statuses.json +439 -0
  24. package/package.json +11 -4
  25. package/schemas/crystal.js +14 -0
  26. package/schemas/effect.js +25 -0
  27. package/schemas/gotchi.js +53 -0
  28. package/schemas/ingameteam.js +14 -0
  29. package/schemas/item.js +13 -0
  30. package/schemas/leaderskill.js +15 -0
  31. package/schemas/leaderskillstatus.js +12 -0
  32. package/schemas/special.js +22 -0
  33. package/schemas/team.js +24 -0
  34. package/schemas/team.json +252 -114
  35. package/scripts/balancing/createTrainingGotchis.js +44 -44
  36. package/scripts/balancing/extractOnchainTraits.js +3 -3
  37. package/scripts/balancing/fixTrainingGotchis.js +41 -41
  38. package/scripts/balancing/processSims.js +5 -5
  39. package/scripts/balancing/sims.js +8 -15
  40. package/scripts/balancing/v1.7/setTeamPositions.js +2 -2
  41. package/scripts/balancing/v1.7.1/setTeamPositions.js +2 -2
  42. package/scripts/balancing/v1.7.2/setTeamPositions.js +2 -2
  43. package/scripts/balancing/v1.7.3/setTeamPositions.js +2 -2
  44. package/scripts/data/dungeon_mob_1.json +87 -0
  45. package/scripts/data/dungeon_mob_2.json +87 -0
  46. package/scripts/data/immaterialTeam1.json +374 -0
  47. package/scripts/data/immaterialTeam2.json +365 -0
  48. package/scripts/generateAllSpecialsLogs.js +93 -0
  49. package/scripts/generateSpecialLogs.js +94 -0
  50. package/scripts/runCampaignBattles.js +41 -0
  51. package/scripts/runLocalBattle.js +6 -3
  52. package/scripts/runLocalDungeon.js +52 -0
  53. package/scripts/runPvPBattle.js +15 -0
  54. package/scripts/runRealBattle.js +8 -8
  55. package/scripts/simRealBattle.js +8 -8
  56. package/scripts/validateBattle.js +12 -14
  57. package/scripts/validateTournament.js +9 -9
  58. package/tests/getModifiedStats.test.js +78 -0
  59. package/utils/errors.js +13 -13
  60. package/utils/transforms.js +2 -8
  61. package/scripts/output/.gitkeep +0 -0
package/schemas/team.json CHANGED
@@ -19,6 +19,9 @@
19
19
  },
20
20
  {
21
21
  "type": "null"
22
+ },
23
+ {
24
+ "$ref": "#/definitions/enemy"
22
25
  }
23
26
  ]
24
27
  }
@@ -34,6 +37,9 @@
34
37
  },
35
38
  {
36
39
  "type": "null"
40
+ },
41
+ {
42
+ "$ref": "#/definitions/enemy"
37
43
  }
38
44
  ]
39
45
  }
@@ -49,6 +55,35 @@
49
55
  "owner": {
50
56
  "type": "string",
51
57
  "pattern": "^0x[a-fA-F0-9]{40}$"
58
+ },
59
+ "startingState": {
60
+ "type": "array",
61
+ "items": {
62
+ "type": "object",
63
+ "properties": {
64
+ "id": {
65
+ "type": "integer"
66
+ },
67
+ "name": {
68
+ "type": "string"
69
+ },
70
+ "health": {
71
+ "type": "integer"
72
+ },
73
+ "statuses": {
74
+ "type": "array",
75
+ "items": {
76
+ "type": "string"
77
+ }
78
+ }
79
+ },
80
+ "required": [
81
+ "id",
82
+ "name",
83
+ "health",
84
+ "statuses"
85
+ ]
86
+ }
52
87
  }
53
88
  },
54
89
  "required": [
@@ -59,6 +94,122 @@
59
94
  ],
60
95
  "additionalProperties": false,
61
96
  "definitions": {
97
+ "special":{
98
+ "type": "object",
99
+ "properties": {
100
+ "id": {
101
+ "type": "integer"
102
+ },
103
+ "class": {
104
+ "type": "string"
105
+ },
106
+ "gotchiClass": {
107
+ "type": "string"
108
+ },
109
+ "name": {
110
+ "type": "string"
111
+ },
112
+ "cooldown": {
113
+ "type": "integer"
114
+ },
115
+ "leaderPassive": {
116
+ "type": "string"
117
+ },
118
+ "createdAt": {
119
+ "type": "string"
120
+ },
121
+ "updatedAt": {
122
+ "type": "string"
123
+ }
124
+ },
125
+ "required": [
126
+ "id",
127
+ "name",
128
+ "cooldown",
129
+ "leaderPassive"
130
+ ],
131
+ "additionalProperties": false
132
+ },
133
+ "item": {
134
+ "type": [
135
+ "object",
136
+ "null"
137
+ ],
138
+ "properties": {
139
+ "id": {
140
+ "type": "integer"
141
+ },
142
+ "name": {
143
+ "type": "string"
144
+ },
145
+ "description": {
146
+ "type": "string"
147
+ },
148
+ "image": {
149
+ "type": "string",
150
+ "format": "uri"
151
+ },
152
+ "rarity": {
153
+ "type": "string",
154
+ "enum": [
155
+ "common",
156
+ "uncommon",
157
+ "rare",
158
+ "legendary",
159
+ "mythical",
160
+ "godlike"
161
+ ]
162
+ },
163
+ "cost": {
164
+ "type": "number"
165
+ },
166
+ "stat": {
167
+ "type": "string",
168
+ "enum": [
169
+ "speed",
170
+ "health",
171
+ "crit",
172
+ "armor",
173
+ "evade",
174
+ "resist",
175
+ "magic",
176
+ "physical",
177
+ "accuracy"
178
+ ]
179
+ },
180
+ "statValue": {
181
+ "type": "integer"
182
+ },
183
+ "createdAt": {
184
+ "type": "string"
185
+ },
186
+ "updatedAt": {
187
+ "type": "string"
188
+ }
189
+ },
190
+ "required": [
191
+ "id",
192
+ "name",
193
+ "description",
194
+ "image",
195
+ "rarity",
196
+ "cost",
197
+ "stat",
198
+ "statValue"
199
+ ],
200
+ "example": {
201
+ "id": 1,
202
+ "name": "Speed +",
203
+ "description": "Increase speed by 1",
204
+ "image": "https://gotchibattler.com/apple-touch-icon.png",
205
+ "rarity": "common",
206
+ "cost": 0.2,
207
+ "stat": "speed",
208
+ "statValue": 1,
209
+ "createdAt": "2022-02-22T22:22:22Z",
210
+ "updatedAt": "2022-02-22T22:22:22Z"
211
+ }
212
+ },
62
213
  "gotchi": {
63
214
  "type": "object",
64
215
  "properties": {
@@ -157,6 +308,9 @@
157
308
  "specialId": {
158
309
  "type": "integer"
159
310
  },
311
+ "enemyId": {
312
+ "type": ["integer", "null"]
313
+ },
160
314
  "hauntId": {
161
315
  "type": ["integer", "null"]
162
316
  },
@@ -191,40 +345,7 @@
191
345
  "type": ["integer", "null"]
192
346
  },
193
347
  "special": {
194
- "type": "object",
195
- "properties": {
196
- "id": {
197
- "type": "integer"
198
- },
199
- "class": {
200
- "type": "string"
201
- },
202
- "gotchiClass": {
203
- "type": "string"
204
- },
205
- "name": {
206
- "type": "string"
207
- },
208
- "cooldown": {
209
- "type": "integer"
210
- },
211
- "leaderPassive": {
212
- "type": "string"
213
- },
214
- "createdAt": {
215
- "type": "string"
216
- },
217
- "updatedAt": {
218
- "type": "string"
219
- }
220
- },
221
- "required": [
222
- "id",
223
- "name",
224
- "cooldown",
225
- "leaderPassive"
226
- ],
227
- "additionalProperties": false
348
+ "$ref": "#/definitions/special"
228
349
  },
229
350
  "itemId": {
230
351
  "type": [
@@ -233,84 +354,104 @@
233
354
  ]
234
355
  },
235
356
  "item": {
357
+ "$ref": "#/definitions/item"
358
+ },
359
+ "statuses": {
360
+ "type": "array",
361
+ "items": {
362
+ "type": "string"
363
+ }
364
+ },
365
+ "createdAt": {
366
+ "type": "string"
367
+ },
368
+ "updatedAt": {
369
+ "type": "string"
370
+ }
371
+ },
372
+ "additionalProperties": false,
373
+ "required": [
374
+ "id",
375
+ "name",
376
+ "speed",
377
+ "health",
378
+ "crit",
379
+ "armor",
380
+ "evade",
381
+ "resist",
382
+ "magic",
383
+ "physical",
384
+ "accuracy",
385
+ "specialId",
386
+ "special"
387
+ ]
388
+ },
389
+ "enemy": {
390
+ "type": "object",
391
+ "properties": {
392
+ "id": {
393
+ "type": "integer"
394
+ },
395
+ "enemyId": {
396
+ "type": "string"
397
+ },
398
+ "name": {
399
+ "type": "string"
400
+ },
401
+ "speed": {
402
+ "type": "integer"
403
+ },
404
+ "health": {
405
+ "type": "integer"
406
+ },
407
+ "startingHealth": {
408
+ "type": "integer"
409
+ },
410
+ "crit": {
411
+ "type": "number"
412
+ },
413
+ "armor": {
414
+ "type": "integer"
415
+ },
416
+ "evade": {
417
+ "type": "number"
418
+ },
419
+ "resist": {
420
+ "type": "integer"
421
+ },
422
+ "magic": {
423
+ "type": "integer"
424
+ },
425
+ "physical": {
426
+ "type": "integer"
427
+ },
428
+ "accuracy": {
429
+ "type": "number"
430
+ },
431
+ "attack": {
432
+ "type": "string",
433
+ "enum": [
434
+ "physical",
435
+ "magic"
436
+ ]
437
+ },
438
+ "actionDelay": {
439
+ "type": "number"
440
+ },
441
+ "specialId": {
442
+ "type": "integer"
443
+ },
444
+ "special": {
445
+ "$ref": "#/definitions/special"
446
+ },
447
+ "itemId": {
236
448
  "type": [
237
- "object",
449
+ "integer",
238
450
  "null"
239
- ],
240
- "properties": {
241
- "id": {
242
- "type": "integer"
243
- },
244
- "name": {
245
- "type": "string"
246
- },
247
- "description": {
248
- "type": "string"
249
- },
250
- "image": {
251
- "type": "string",
252
- "format": "uri"
253
- },
254
- "rarity": {
255
- "type": "string",
256
- "enum": [
257
- "common",
258
- "uncommon",
259
- "rare",
260
- "legendary",
261
- "mythical",
262
- "godlike"
263
- ]
264
- },
265
- "cost": {
266
- "type": "number"
267
- },
268
- "stat": {
269
- "type": "string",
270
- "enum": [
271
- "speed",
272
- "health",
273
- "crit",
274
- "armor",
275
- "evade",
276
- "resist",
277
- "magic",
278
- "physical",
279
- "accuracy"
280
- ]
281
- },
282
- "statValue": {
283
- "type": "integer"
284
- },
285
- "createdAt": {
286
- "type": "string"
287
- },
288
- "updatedAt": {
289
- "type": "string"
290
- }
291
- },
292
- "required": [
293
- "id",
294
- "name",
295
- "description",
296
- "image",
297
- "rarity",
298
- "cost",
299
- "stat",
300
- "statValue"
301
- ],
302
- "example": {
303
- "id": 1,
304
- "name": "Speed +",
305
- "description": "Increase speed by 1",
306
- "image": "https://gotchibattler.com/apple-touch-icon.png",
307
- "rarity": "common",
308
- "cost": 0.2,
309
- "stat": "speed",
310
- "statValue": 1,
311
- "createdAt": "2022-02-22T22:22:22Z",
312
- "updatedAt": "2022-02-22T22:22:22Z"
313
- }
451
+ ]
452
+ },
453
+ "item": {
454
+ "$ref": "#/definitions/item"
314
455
  },
315
456
  "statuses": {
316
457
  "type": "array",
@@ -329,6 +470,7 @@
329
470
  "required": [
330
471
  "id",
331
472
  "name",
473
+ "enemyId",
332
474
  "speed",
333
475
  "health",
334
476
  "crit",
@@ -338,10 +480,6 @@
338
480
  "magic",
339
481
  "physical",
340
482
  "accuracy",
341
- "svgFront",
342
- "svgBack",
343
- "svgLeft",
344
- "svgRight",
345
483
  "specialId",
346
484
  "special"
347
485
  ]
@@ -2,60 +2,60 @@ const fs = require('fs')
2
2
 
3
3
  const specials = [
4
4
  {
5
- "id": 1,
6
- "class": "Ninja",
7
- "name": "Spectral strike",
8
- "cooldown": 0,
9
- "leaderPassive": "Sharpen blades"
5
+ 'id': 1,
6
+ 'class': 'Ninja',
7
+ 'name': 'Spectral strike',
8
+ 'cooldown': 0,
9
+ 'leaderPassive': 'Sharpen blades'
10
10
  },
11
11
  {
12
- "id": 2,
13
- "class": "Enlightened",
14
- "name": "Meditate",
15
- "cooldown": 0,
16
- "leaderPassive": "Cloud of Zen"
12
+ 'id': 2,
13
+ 'class': 'Enlightened',
14
+ 'name': 'Meditate',
15
+ 'cooldown': 0,
16
+ 'leaderPassive': 'Cloud of Zen'
17
17
  },
18
18
  {
19
- "id": 3,
20
- "class": "Cleaver",
21
- "name": "Cleave",
22
- "cooldown": 2,
23
- "leaderPassive": "Frenzy"
19
+ 'id': 3,
20
+ 'class': 'Cleaver',
21
+ 'name': 'Cleave',
22
+ 'cooldown': 2,
23
+ 'leaderPassive': 'Frenzy'
24
24
  },
25
25
  {
26
- "id": 4,
27
- "class": "Tank",
28
- "name": "Taunt",
29
- "cooldown": 0,
30
- "leaderPassive": "Fortify"
26
+ 'id': 4,
27
+ 'class': 'Tank',
28
+ 'name': 'Taunt',
29
+ 'cooldown': 0,
30
+ 'leaderPassive': 'Fortify'
31
31
  },
32
32
  {
33
- "id": 5,
34
- "class": "Cursed",
35
- "name": "Curse",
36
- "cooldown": 0,
37
- "leaderPassive": "Spread the fear"
33
+ 'id': 5,
34
+ 'class': 'Cursed',
35
+ 'name': 'Curse',
36
+ 'cooldown': 0,
37
+ 'leaderPassive': 'Spread the fear'
38
38
  },
39
39
  {
40
- "id": 6,
41
- "class": "Healer",
42
- "name": "Blessing",
43
- "cooldown": 0,
44
- "leaderPassive": "Cleansing Aura"
40
+ 'id': 6,
41
+ 'class': 'Healer',
42
+ 'name': 'Blessing',
43
+ 'cooldown': 0,
44
+ 'leaderPassive': 'Cleansing Aura'
45
45
  },
46
46
  {
47
- "id": 7,
48
- "class": "Mage",
49
- "name": "Thunder",
50
- "cooldown": 2,
51
- "leaderPassive": "Channel the coven"
47
+ 'id': 7,
48
+ 'class': 'Mage',
49
+ 'name': 'Thunder',
50
+ 'cooldown': 2,
51
+ 'leaderPassive': 'Channel the coven'
52
52
  },
53
53
  {
54
- "id": 8,
55
- "class": "Troll",
56
- "name": "Devestating Smash",
57
- "cooldown": 2,
58
- "leaderPassive": "Clan momentum"
54
+ 'id': 8,
55
+ 'class': 'Troll',
56
+ 'name': 'Devestating Smash',
57
+ 'cooldown': 2,
58
+ 'leaderPassive': 'Clan momentum'
59
59
  }
60
60
  ]
61
61
 
@@ -182,8 +182,8 @@ const main = (version) => {
182
182
  gotchi.svgBack = `https://storage.googleapis.com/gotchi-battler-qa_gotchis/training/${className.toLowerCase()}_${p.toLowerCase()}_back.png`
183
183
  gotchi.svgLeft = `https://storage.googleapis.com/gotchi-battler-qa_gotchis/training/${className.toLowerCase()}_${p.toLowerCase()}_left.png`
184
184
  gotchi.svgRight = `https://storage.googleapis.com/gotchi-battler-qa_gotchis/training/${className.toLowerCase()}_${p.toLowerCase()}_right.png`
185
- gotchi.createdAt = "2023-09-09 12:10:01"
186
- gotchi.updatedAt = "2024-06-05 16:34:00"
185
+ gotchi.createdAt = '2023-09-09 12:10:01'
186
+ gotchi.updatedAt = '2024-06-05 16:34:00'
187
187
  gotchi.special = specials.find(s => s.id === gotchi.specialId)
188
188
 
189
189
  trainingGotchis.push(gotchi)
@@ -197,11 +197,11 @@ const main = (version) => {
197
197
 
198
198
  trainingGotchis.push(...avgGotchis)
199
199
 
200
- fs.writeFileSync(`./training_gotchis.json`, JSON.stringify(trainingGotchis, null, 2))
200
+ fs.writeFileSync('./training_gotchis.json', JSON.stringify(trainingGotchis, null, 2))
201
201
  }
202
202
 
203
203
  const createAvgGotchs = (trainingGotchis) => {
204
- const statsToOverwrite = ["speed", "health", "crit", "armor", "evade", "resist", "accuracy"]
204
+ const statsToOverwrite = ['speed', 'health', 'crit', 'armor', 'evade', 'resist', 'accuracy']
205
205
 
206
206
  const avgGotchis = [];
207
207
 
@@ -51,10 +51,10 @@ const main = () => {
51
51
 
52
52
  fs.writeFileSync('./training_gotchis_traits.json', JSON.stringify(onchainTraits, (key, value) => {
53
53
  if (Array.isArray(value)) {
54
- return JSON.stringify(value); // Convert array to a string
54
+ return JSON.stringify(value) // Convert array to a string
55
55
  }
56
- return value;
57
- }, 2).replace(/"\[(.*?)\]"/g, "[$1]"))
56
+ return value
57
+ }, 2).replace(/"\[(.*?)\]"/g, '[$1]'))
58
58
  }
59
59
 
60
60
  // node scripts/balancing/extractOnchainTraits.js