gotchi-battler-game-logic 4.0.0 → 4.0.2

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.
@@ -36,7 +36,7 @@ const {
36
36
  * @param {String} options.isBoss A boolean to determine if team2 is a boss
37
37
  * @returns {Object} logs The battle logs
38
38
  */
39
- const gameLoop = (team1, team2, seed, options = { debug: false, type: 'pve', campaign: {}, isBoss: false }) => {
39
+ const gameLoop = (team1, team2, seed, options = { debug: false, type: 'training', campaign: {}, isBoss: false }) => {
40
40
  if (!seed) throw new Error('Seed not found')
41
41
 
42
42
  // Validate team objects
@@ -53,7 +53,7 @@ const gameLoop = (team1, team2, seed, options = { debug: false, type: 'pve', cam
53
53
  meta: {
54
54
  seed,
55
55
  timestamp: new Date(),
56
- type: options.type || 'pve',
56
+ type: options.type || 'training',
57
57
  campaign: options.campaign || {},
58
58
  isBoss: options.isBoss || false
59
59
  },
@@ -449,32 +449,25 @@ const attack = (attackingGotchi, attackingTeam, defendingTeam, rng, isSpecial =
449
449
  // Handle the effect
450
450
  const specialEffectResults = handleSpecialEffects(attackingTeam, attackingGotchi, target, specialEffect, rng)
451
451
 
452
- if (specialEffectResults) {
453
- if (specialEffectResults.actionEffect) {
454
- if (targetActionEffect) {
455
- // If target is same as the actionEffect then just add statuses to the actionEffect
456
- if (targetActionEffect.target && targetActionEffect.target === specialEffectResults.actionEffect.target) {
457
- targetActionEffect.statuses.push(...specialEffectResults.actionEffect.statuses)
458
- } else {
459
- // If not then add to additionalEffects
460
- targetAdditionalEffects.push(specialEffectResults.actionEffect)
461
- }
462
- } else {
463
- targetActionEffect = specialEffectResults.actionEffect
464
- }
452
+ // Do we already have an action effect with attack damage or healing?
453
+ if (targetActionEffect) {
454
+ // If target is same as the actionEffect then just add statuses to the actionEffect
455
+ if (targetActionEffect.target && targetActionEffect.target === specialEffectResults.actionEffect.target) {
456
+ targetActionEffect.statuses.push(...specialEffectResults.actionEffect.statuses)
457
+ } else {
458
+ // If not then add to additionalEffects
459
+ targetAdditionalEffects.push(specialEffectResults.actionEffect)
465
460
  }
461
+ } else {
462
+ targetActionEffect = specialEffectResults.actionEffect
463
+ }
466
464
 
467
- if (specialEffectResults.additionalEffects) {
468
- targetAdditionalEffects.push(...specialEffectResults.additionalEffects)
469
- }
465
+ targetAdditionalEffects.push(...specialEffectResults.additionalEffects)
470
466
 
471
- if (specialEffectResults.statusesExpired) {
472
- statusesExpired.push(...specialEffectResults.statusesExpired)
473
- }
467
+ statusesExpired.push(...specialEffectResults.statusesExpired)
474
468
 
475
- if (specialEffectResults.repeatAttack) {
476
- repeatAttack = true
477
- }
469
+ if (specialEffectResults.repeatAttack) {
470
+ repeatAttack = true
478
471
  }
479
472
  }
480
473
  })
@@ -598,22 +591,14 @@ const attack = (attackingGotchi, attackingTeam, defendingTeam, rng, isSpecial =
598
591
  targets.forEach((target) => {
599
592
  const specialEffectResults = handleSpecialEffects(attackingTeam, attackingGotchi, target, specialEffect, rng)
600
593
 
601
- if (specialEffectResults) {
602
- if (specialEffectResults.actionEffect) {
603
- additionalEffects.push(specialEffectResults.actionEffect)
604
- }
594
+ additionalEffects.push(specialEffectResults.actionEffect)
605
595
 
606
- if (specialEffectResults.additionalEffects) {
607
- additionalEffects.push(...specialEffectResults.additionalEffects)
608
- }
596
+ additionalEffects.push(...specialEffectResults.additionalEffects)
609
597
 
610
- if (specialEffectResults.statusesExpired) {
611
- statusesExpired.push(...specialEffectResults.statusesExpired)
612
- }
598
+ statusesExpired.push(...specialEffectResults.statusesExpired)
613
599
 
614
- if (specialEffectResults.repeatAttack) {
615
- repeatAttack = true
616
- }
600
+ if (specialEffectResults.repeatAttack) {
601
+ repeatAttack = true
617
602
  }
618
603
  })
619
604
  }
@@ -629,26 +614,35 @@ const attack = (attackingGotchi, attackingTeam, defendingTeam, rng, isSpecial =
629
614
  }
630
615
 
631
616
  const handleSpecialEffects = (attackingTeam, attackingGotchi, target, specialEffect, rng) => {
632
- if (specialEffect.chance && specialEffect.chance < 1 && rng() > specialEffect.chance) {
633
- return false
634
- }
635
-
636
617
  const actionEffect = {
637
618
  target: target.id,
638
619
  statuses: [],
639
- outcome: 'success'
620
+ outcome: 'failed'
640
621
  }
641
-
622
+
642
623
  const additionalEffects = []
643
624
  const statusesExpired = []
644
625
  let repeatAttack = false
645
626
 
627
+ // Check for chance of the special effect
628
+ if (specialEffect.chance && specialEffect.chance < 1 && rng() > specialEffect.chance) {
629
+ return {
630
+ actionEffect,
631
+ additionalEffects,
632
+ statusesExpired,
633
+ repeatAttack
634
+ }
635
+ }
636
+
646
637
  switch (specialEffect.effectType) {
647
638
  case 'status': {
648
639
  // Focus/resistance check if target is not on the same team as the attacking gotchi
649
640
  if (focusCheck(attackingTeam, attackingGotchi, target, rng)) {
650
641
  addStatusToGotchi(target, specialEffect.status)
651
642
  actionEffect.statuses.push(specialEffect.status)
643
+ actionEffect.outcome = 'success'
644
+ } else {
645
+ actionEffect.outcome = 'resisted'
652
646
  }
653
647
  break
654
648
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gotchi-battler-game-logic",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "mocha \"tests/**/*.test.js\"",
@@ -3,7 +3,7 @@
3
3
  "front": [
4
4
  null,
5
5
  {
6
- "id": 2,
6
+ "id": 42,
7
7
  "onchainId": 22892,
8
8
  "name": "Chonk",
9
9
  "type": "gotchi",
@@ -14,11 +14,11 @@
14
14
  "attack": 176,
15
15
  "defense": 157,
16
16
  "criticalRate": 38.6,
17
- "criticalDamage": 158.2,
17
+ "criticalDamage": 158,
18
18
  "resist": 182,
19
19
  "focus": 182,
20
- "createdAt": "2025-11-24T16:54:05.342Z",
21
- "updatedAt": "2025-11-24T16:54:05.342Z",
20
+ "createdAt": "2025-12-01T15:01:53.381Z",
21
+ "updatedAt": "2025-12-01T15:01:53.381Z",
22
22
  "gotchiClass": "tank",
23
23
  "special": "fortress_stance",
24
24
  "leaderSkill": "dig_in",
@@ -97,7 +97,7 @@
97
97
  },
98
98
  null,
99
99
  {
100
- "id": 4,
100
+ "id": 44,
101
101
  "onchainId": 13536,
102
102
  "name": "Bearded",
103
103
  "type": "gotchi",
@@ -108,11 +108,11 @@
108
108
  "attack": 175,
109
109
  "defense": 132,
110
110
  "criticalRate": 45.7,
111
- "criticalDamage": 172.7,
111
+ "criticalDamage": 173,
112
112
  "resist": 151,
113
113
  "focus": 176,
114
- "createdAt": "2025-11-24T16:54:05.343Z",
115
- "updatedAt": "2025-11-24T16:54:05.343Z",
114
+ "createdAt": "2025-12-01T15:01:53.383Z",
115
+ "updatedAt": "2025-12-01T15:01:53.383Z",
116
116
  "gotchiClass": "ninja",
117
117
  "special": "precise_shuriken",
118
118
  "leaderSkill": "known_vulnerability",
@@ -165,7 +165,7 @@
165
165
  ],
166
166
  "back": [
167
167
  {
168
- "id": 1,
168
+ "id": 41,
169
169
  "onchainId": 16559,
170
170
  "name": "Immaterial",
171
171
  "type": "gotchi",
@@ -176,11 +176,11 @@
176
176
  "attack": 200,
177
177
  "defense": 172,
178
178
  "criticalRate": 47.8,
179
- "criticalDamage": 184.6,
179
+ "criticalDamage": 185,
180
180
  "resist": 199,
181
181
  "focus": 233,
182
- "createdAt": "2025-11-24T16:54:05.340Z",
183
- "updatedAt": "2025-11-24T16:54:05.340Z",
182
+ "createdAt": "2025-12-01T15:01:53.378Z",
183
+ "updatedAt": "2025-12-01T15:01:53.378Z",
184
184
  "gotchiClass": "mage",
185
185
  "special": "tornado",
186
186
  "leaderSkill": "obsessive_studies",
@@ -236,7 +236,7 @@
236
236
  },
237
237
  null,
238
238
  {
239
- "id": 3,
239
+ "id": 43,
240
240
  "onchainId": 22249,
241
241
  "name": "575 Zoomer",
242
242
  "type": "gotchi",
@@ -247,11 +247,11 @@
247
247
  "attack": 201,
248
248
  "defense": 156,
249
249
  "criticalRate": 38.3,
250
- "criticalDamage": 172.7,
250
+ "criticalDamage": 173,
251
251
  "resist": 152,
252
252
  "focus": 152,
253
- "createdAt": "2025-11-24T16:54:05.342Z",
254
- "updatedAt": "2025-11-24T16:54:05.342Z",
253
+ "createdAt": "2025-12-01T15:01:53.382Z",
254
+ "updatedAt": "2025-12-01T15:01:53.382Z",
255
255
  "gotchiClass": "ninja",
256
256
  "special": "precise_shuriken",
257
257
  "leaderSkill": "known_vulnerability",
@@ -302,7 +302,7 @@
302
302
  },
303
303
  null,
304
304
  {
305
- "id": 5,
305
+ "id": 45,
306
306
  "onchainId": 236,
307
307
  "name": "Terry",
308
308
  "type": "gotchi",
@@ -313,11 +313,11 @@
313
313
  "attack": 155,
314
314
  "defense": 116,
315
315
  "criticalRate": 38.1,
316
- "criticalDamage": 160.1,
316
+ "criticalDamage": 160,
317
317
  "resist": 110,
318
318
  "focus": 132,
319
- "createdAt": "2025-11-24T16:54:05.343Z",
320
- "updatedAt": "2025-11-24T16:54:05.343Z",
319
+ "createdAt": "2025-12-01T15:01:53.383Z",
320
+ "updatedAt": "2025-12-01T15:01:53.383Z",
321
321
  "gotchiClass": "ninja",
322
322
  "special": "precise_shuriken",
323
323
  "leaderSkill": "known_vulnerability",
@@ -368,7 +368,7 @@
368
368
  }
369
369
  ]
370
370
  },
371
- "leader": 1,
371
+ "leader": 41,
372
372
  "name": "Immaterial Team 1",
373
373
  "owner": "0xfe698c212526f15cc25af671beba14aac309457f"
374
374
  }
@@ -3,7 +3,7 @@
3
3
  "front": [
4
4
  null,
5
5
  {
6
- "id": 7,
6
+ "id": 47,
7
7
  "onchainId": 23921,
8
8
  "name": "Godly",
9
9
  "type": "gotchi",
@@ -14,11 +14,11 @@
14
14
  "attack": 210,
15
15
  "defense": 133,
16
16
  "criticalRate": 50.1,
17
- "criticalDamage": 168.1,
17
+ "criticalDamage": 168,
18
18
  "resist": 152,
19
19
  "focus": 152,
20
- "createdAt": "2025-11-24T16:54:05.374Z",
21
- "updatedAt": "2025-11-24T16:54:05.374Z",
20
+ "createdAt": "2025-12-01T15:01:53.416Z",
21
+ "updatedAt": "2025-12-01T15:01:53.416Z",
22
22
  "gotchiClass": "troll",
23
23
  "special": "furious_bash",
24
24
  "leaderSkill": "smash",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  null,
71
71
  {
72
- "id": 9,
72
+ "id": 49,
73
73
  "onchainId": 8062,
74
74
  "name": "Magestic",
75
75
  "type": "gotchi",
@@ -80,11 +80,11 @@
80
80
  "attack": 175,
81
81
  "defense": 132,
82
82
  "criticalRate": 50.2,
83
- "criticalDamage": 157.7,
83
+ "criticalDamage": 158,
84
84
  "resist": 181,
85
85
  "focus": 173,
86
- "createdAt": "2025-11-24T16:54:05.374Z",
87
- "updatedAt": "2025-11-24T16:54:05.374Z",
86
+ "createdAt": "2025-12-01T15:01:53.417Z",
87
+ "updatedAt": "2025-12-01T15:01:53.417Z",
88
88
  "gotchiClass": "cleaver",
89
89
  "special": "sword_breaker",
90
90
  "leaderSkill": "sharp_wits",
@@ -146,7 +146,7 @@
146
146
  ],
147
147
  "back": [
148
148
  {
149
- "id": 6,
149
+ "id": 46,
150
150
  "onchainId": 13681,
151
151
  "name": "Artemis",
152
152
  "type": "gotchi",
@@ -157,11 +157,11 @@
157
157
  "attack": 193,
158
158
  "defense": 166,
159
159
  "criticalRate": 45.1,
160
- "criticalDamage": 175.4,
160
+ "criticalDamage": 175,
161
161
  "resist": 186,
162
162
  "focus": 217,
163
- "createdAt": "2025-11-24T16:54:05.373Z",
164
- "updatedAt": "2025-11-24T16:54:05.373Z",
163
+ "createdAt": "2025-12-01T15:01:53.416Z",
164
+ "updatedAt": "2025-12-01T15:01:53.416Z",
165
165
  "gotchiClass": "mage",
166
166
  "special": "tornado",
167
167
  "leaderSkill": "obsessive_studies",
@@ -217,7 +217,7 @@
217
217
  },
218
218
  null,
219
219
  {
220
- "id": 8,
220
+ "id": 48,
221
221
  "onchainId": 19172,
222
222
  "name": "Gatekeeper",
223
223
  "type": "gotchi",
@@ -228,11 +228,11 @@
228
228
  "attack": 176,
229
229
  "defense": 156,
230
230
  "criticalRate": 38.5,
231
- "criticalDamage": 168.9,
231
+ "criticalDamage": 169,
232
232
  "resist": 153,
233
233
  "focus": 186,
234
- "createdAt": "2025-11-24T16:54:05.374Z",
235
- "updatedAt": "2025-11-24T16:54:05.374Z",
234
+ "createdAt": "2025-12-01T15:01:53.416Z",
235
+ "updatedAt": "2025-12-01T15:01:53.416Z",
236
236
  "gotchiClass": "mage",
237
237
  "special": "tornado",
238
238
  "leaderSkill": "obsessive_studies",
@@ -288,7 +288,7 @@
288
288
  },
289
289
  null,
290
290
  {
291
- "id": 10,
291
+ "id": 50,
292
292
  "onchainId": 4751,
293
293
  "name": "best ever",
294
294
  "type": "gotchi",
@@ -299,11 +299,11 @@
299
299
  "attack": 156,
300
300
  "defense": 117,
301
301
  "criticalRate": 37.5,
302
- "criticalDamage": 148.1,
302
+ "criticalDamage": 148,
303
303
  "resist": 135,
304
304
  "focus": 136,
305
- "createdAt": "2025-11-24T16:54:05.374Z",
306
- "updatedAt": "2025-11-24T16:54:05.374Z",
305
+ "createdAt": "2025-12-01T15:01:53.417Z",
306
+ "updatedAt": "2025-12-01T15:01:53.417Z",
307
307
  "gotchiClass": "mage",
308
308
  "special": "tornado",
309
309
  "leaderSkill": "obsessive_studies",
@@ -359,7 +359,7 @@
359
359
  }
360
360
  ]
361
361
  },
362
- "leader": 6,
362
+ "leader": 46,
363
363
  "name": "Immaterial Team 2",
364
364
  "owner": "0xfe698c212526f15cc25af671beba14aac309457f"
365
365
  }