gotchi-battler-game-logic 2.0.7 → 3.0.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.
- package/.vscode/settings.json +4 -4
- package/Dockerfile +9 -9
- package/README.md +49 -49
- package/cloudbuild.yaml +27 -27
- package/constants/tournamentManagerAbi.json +208 -208
- package/game-logic/index.js +7 -6
- package/game-logic/v1.4/constants.js +114 -114
- package/game-logic/v1.4/index.js +1366 -1366
- package/game-logic/v1.6/constants.js +123 -123
- package/game-logic/v1.6/index.js +1406 -1406
- package/game-logic/v1.7/constants.js +142 -140
- package/game-logic/v1.7/helpers.js +610 -593
- package/game-logic/v1.7/index.js +802 -795
- package/game-logic/v1.8/constants.js +135 -0
- package/game-logic/v1.8/helpers.js +628 -0
- package/game-logic/v1.8/index.js +826 -0
- package/index.js +12 -12
- package/package.json +26 -26
- package/schemas/team.json +349 -343
- package/scripts/balancing/createCSV.js +126 -126
- package/scripts/balancing/createTrainingGotchis.js +267 -0
- package/scripts/balancing/extractOnchainTraits.js +61 -0
- package/scripts/balancing/fixTrainingGotchis.js +155 -259
- package/scripts/balancing/processSims.js +229 -229
- package/scripts/balancing/sims.js +278 -278
- package/scripts/balancing/v1.7/class_combos.js +43 -43
- package/scripts/balancing/v1.7/mapGotchi.js +119 -0
- package/scripts/balancing/v1.7/setTeamPositions.js +105 -105
- package/scripts/balancing/v1.7/training_gotchis.json +20161 -20161
- package/scripts/balancing/v1.7/training_gotchis_traits.json +520 -0
- package/scripts/balancing/v1.7/trait_combos.json +9 -9
- package/scripts/balancing/v1.7.1/class_combos.js +43 -43
- package/scripts/balancing/v1.7.1/mapGotchi.js +119 -0
- package/scripts/balancing/v1.7.1/setTeamPositions.js +122 -122
- package/scripts/balancing/v1.7.1/training_gotchis.json +22401 -22401
- package/scripts/balancing/v1.7.1/training_gotchis_traits.json +520 -0
- package/scripts/balancing/v1.7.1/trait_combos.json +9 -9
- package/scripts/balancing/v1.7.2/class_combos.js +44 -0
- package/scripts/balancing/v1.7.2/mapGotchi.js +157 -0
- package/scripts/balancing/v1.7.2/setTeamPositions.js +122 -0
- package/scripts/balancing/v1.7.2/training_gotchis.json +22402 -0
- package/scripts/balancing/v1.7.2/training_gotchis_traits.json +520 -0
- package/scripts/balancing/v1.7.2/trait_combos.json +10 -0
- package/scripts/balancing/v1.7.3/class_combos.js +44 -0
- package/scripts/balancing/v1.7.3/mapGotchi.js +164 -0
- package/scripts/balancing/v1.7.3/setTeamPositions.js +122 -0
- package/scripts/balancing/v1.7.3/training_gotchis.json +22402 -0
- package/scripts/balancing/v1.7.3/training_gotchis_traits.json +37 -0
- package/scripts/balancing/v1.7.3/trait_combos.json +10 -0
- package/scripts/data/team1.json +213 -213
- package/scripts/data/team2.json +200 -200
- package/scripts/data/tournaments.json +71 -66
- package/scripts/{runBattle.js → runLocalBattle.js} +18 -18
- package/scripts/runRealBattle.js +52 -0
- package/scripts/simRealBattle.js +121 -0
- package/scripts/validateBattle.js +83 -70
- package/scripts/validateTournament.js +101 -101
- package/utils/contracts.js +12 -12
- package/utils/errors.js +29 -29
- package/utils/mapGotchi.js +119 -0
- package/utils/transforms.js +89 -88
- package/utils/validations.js +39 -39
- package/debug.log +0 -2
- package/game-logic/v1.6/debug.log +0 -1
- package/game-logic/v1.7/debug.log +0 -3
- package/scripts/data/debug.log +0 -2
- package/scripts/debug.log +0 -1
|
@@ -1,260 +1,156 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const trainingGotchis = require('./v1.7/training_gotchis.json')
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
let newTrait
|
|
157
|
-
if (trait !== 'accuracy') {
|
|
158
|
-
if (traitMap.isNegative) {
|
|
159
|
-
newTrait = onchainVal < 50 ? Math.round(base + (traitValues[traitMap.traitKey] * traitMap.multiplier)) : base
|
|
160
|
-
} else {
|
|
161
|
-
newTrait = onchainVal < 50 ? base : Math.round(base + (traitValues[traitMap.traitKey] * traitMap.multiplier))
|
|
162
|
-
}
|
|
163
|
-
} else {
|
|
164
|
-
newTrait = base + ((traitValues[4] + traitValues[5]) * traitMap.multiplier)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (newTrait !== gotchi[trait]) gotchi[trait] = newTrait
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const addAvgGotchs = () => {
|
|
172
|
-
const statsToOverwrite = ["speed", "health", "crit", "armor", "evade", "resist", "accuracy"]
|
|
173
|
-
|
|
174
|
-
const avgGotchis = [];
|
|
175
|
-
|
|
176
|
-
// Add magic gotchis
|
|
177
|
-
['magic', 'physical'].forEach((brainValue) => {
|
|
178
|
-
powerLevels.forEach((powerLevel) => {
|
|
179
|
-
classes.forEach((className) => {
|
|
180
|
-
// Find all gotchis with the same class and power level
|
|
181
|
-
// Names are in the format "Godlike ++++ Ninja"
|
|
182
|
-
const gotchis = trainingGotchis.filter(gotchi => gotchi.name.includes(powerLevel) && gotchi.name.includes(className))
|
|
183
|
-
|
|
184
|
-
// Copy over one of the gotchis
|
|
185
|
-
const avgGotchi = JSON.parse(JSON.stringify(gotchis[0]))
|
|
186
|
-
|
|
187
|
-
// Add an id
|
|
188
|
-
avgGotchi.id = trainingGotchis.length + avgGotchis.length + 1
|
|
189
|
-
|
|
190
|
-
// Overwrite the name
|
|
191
|
-
avgGotchi.name = `${powerLevel} avg-${brainValue} ${className}`
|
|
192
|
-
|
|
193
|
-
// Overwrite the stats
|
|
194
|
-
statsToOverwrite.forEach((stat) => {
|
|
195
|
-
const total = gotchis.reduce((acc, gotchi) => acc + gotchi[stat], 0)
|
|
196
|
-
avgGotchi[stat] = Math.round(total / gotchis.length)
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
// Get the highest/lowest magic value
|
|
200
|
-
const magicValues = gotchis.map(gotchi => gotchi.magic)
|
|
201
|
-
const highestMagic = Math.max(...magicValues)
|
|
202
|
-
const lowestMagic = Math.min(...magicValues)
|
|
203
|
-
|
|
204
|
-
// Get the highest/lowest physical value
|
|
205
|
-
const physicalValues = gotchis.map(gotchi => gotchi.physical)
|
|
206
|
-
const highestPhysical = Math.max(...physicalValues)
|
|
207
|
-
const lowestPhysical = Math.min(...physicalValues)
|
|
208
|
-
|
|
209
|
-
// If this is a magic gotchi then set the magic value to the highest
|
|
210
|
-
if (brainValue === 'magic') {
|
|
211
|
-
avgGotchi.magic = highestMagic
|
|
212
|
-
avgGotchi.physical = lowestPhysical
|
|
213
|
-
avgGotchi.attack = 'magic'
|
|
214
|
-
} else {
|
|
215
|
-
avgGotchi.magic = lowestMagic
|
|
216
|
-
avgGotchi.physical = highestPhysical
|
|
217
|
-
avgGotchi.attack = 'physical'
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
avgGotchis.push(avgGotchi)
|
|
221
|
-
})
|
|
222
|
-
})
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
trainingGotchis.push(...avgGotchis)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Sort the gotchis by id
|
|
229
|
-
trainingGotchis.sort((a, b) => a.id - b.id)
|
|
230
|
-
|
|
231
|
-
trainingGotchis.forEach(gotchi => {
|
|
232
|
-
// Add special to gotchi
|
|
233
|
-
const special = specials.find(special => special.id === gotchi.specialId)
|
|
234
|
-
|
|
235
|
-
if (!special) throw new Error(`Special not found for gotchi: "${gotchi.name}"`)
|
|
236
|
-
|
|
237
|
-
gotchi.special = special
|
|
238
|
-
|
|
239
|
-
// Fix names
|
|
240
|
-
// If name ends with a + or - then add the class name at the end
|
|
241
|
-
if (gotchi.name.endsWith('+') || gotchi.name.endsWith('-')) {
|
|
242
|
-
gotchi.name = `${gotchi.name} ${classes[gotchi.specialId - 1]}`
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Remove extra fields
|
|
246
|
-
delete gotchi.tier
|
|
247
|
-
delete gotchi.class
|
|
248
|
-
delete gotchi.stats_brs
|
|
249
|
-
|
|
250
|
-
// Make sure the gotchi has the correct traits
|
|
251
|
-
fixTraits(gotchi)
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
// Add the average gotchis
|
|
255
|
-
addAvgGotchs()
|
|
256
|
-
|
|
257
|
-
// Write the updated trainingGotchis to a new file
|
|
258
|
-
fs.writeFileSync('./training_gotchis1.json', JSON.stringify(trainingGotchis, null, '\t'))
|
|
259
|
-
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const trainingGotchis = require('./v1.7.2/training_gotchis.json')
|
|
3
|
+
const { mapGotchi } = require('../../utils/mapGotchi')
|
|
4
|
+
|
|
5
|
+
const specials = [
|
|
6
|
+
{
|
|
7
|
+
"id": 1,
|
|
8
|
+
"class": "Ninja",
|
|
9
|
+
"name": "Spectral strike",
|
|
10
|
+
"cooldown": 0,
|
|
11
|
+
"leaderPassive": "Sharpen blades"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": 2,
|
|
15
|
+
"class": "Enlightened",
|
|
16
|
+
"name": "Meditate",
|
|
17
|
+
"cooldown": 0,
|
|
18
|
+
"leaderPassive": "Cloud of Zen"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": 3,
|
|
22
|
+
"class": "Cleaver",
|
|
23
|
+
"name": "Cleave",
|
|
24
|
+
"cooldown": 2,
|
|
25
|
+
"leaderPassive": "Frenzy"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": 4,
|
|
29
|
+
"class": "Tank",
|
|
30
|
+
"name": "Taunt",
|
|
31
|
+
"cooldown": 0,
|
|
32
|
+
"leaderPassive": "Fortify"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": 5,
|
|
36
|
+
"class": "Cursed",
|
|
37
|
+
"name": "Curse",
|
|
38
|
+
"cooldown": 0,
|
|
39
|
+
"leaderPassive": "Spread the fear"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": 6,
|
|
43
|
+
"class": "Healer",
|
|
44
|
+
"name": "Blessing",
|
|
45
|
+
"cooldown": 0,
|
|
46
|
+
"leaderPassive": "Cleansing Aura"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": 7,
|
|
50
|
+
"class": "Mage",
|
|
51
|
+
"name": "Thunder",
|
|
52
|
+
"cooldown": 2,
|
|
53
|
+
"leaderPassive": "Channel the coven"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": 8,
|
|
57
|
+
"class": "Troll",
|
|
58
|
+
"name": "Devestating Smash",
|
|
59
|
+
"cooldown": 2,
|
|
60
|
+
"leaderPassive": "Clan momentum"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
const classes = ['Ninja','Enlightened','Cleaver','Tank','Cursed','Healer', 'Mage', 'Troll']
|
|
65
|
+
const powerLevels = ['Godlike', 'Mythical', 'Legendary', 'Rare', 'Uncommon', 'Common', 'Garbage']
|
|
66
|
+
|
|
67
|
+
const addAvgGotchs = () => {
|
|
68
|
+
const statsToOverwrite = ["speed", "health", "crit", "armor", "evade", "resist", "accuracy"]
|
|
69
|
+
|
|
70
|
+
const avgGotchis = [];
|
|
71
|
+
|
|
72
|
+
// Add magic gotchis
|
|
73
|
+
['magic', 'physical'].forEach((brainValue) => {
|
|
74
|
+
powerLevels.forEach((powerLevel) => {
|
|
75
|
+
classes.forEach((className) => {
|
|
76
|
+
// Find all gotchis with the same class and power level
|
|
77
|
+
// Names are in the format "Godlike ++++ Ninja"
|
|
78
|
+
const gotchis = trainingGotchis.filter(gotchi => gotchi.name.includes(powerLevel) && gotchi.name.includes(className))
|
|
79
|
+
|
|
80
|
+
// Copy over one of the gotchis
|
|
81
|
+
const avgGotchi = JSON.parse(JSON.stringify(gotchis[0]))
|
|
82
|
+
|
|
83
|
+
// Add an id
|
|
84
|
+
avgGotchi.id = trainingGotchis.length + avgGotchis.length + 1
|
|
85
|
+
|
|
86
|
+
// Overwrite the name
|
|
87
|
+
avgGotchi.name = `${powerLevel} avg-${brainValue} ${className}`
|
|
88
|
+
|
|
89
|
+
// Overwrite the stats
|
|
90
|
+
statsToOverwrite.forEach((stat) => {
|
|
91
|
+
const total = gotchis.reduce((acc, gotchi) => acc + gotchi[stat], 0)
|
|
92
|
+
avgGotchi[stat] = Math.round(total / gotchis.length)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
// Get the highest/lowest magic value
|
|
96
|
+
const magicValues = gotchis.map(gotchi => gotchi.magic)
|
|
97
|
+
const highestMagic = Math.max(...magicValues)
|
|
98
|
+
const lowestMagic = Math.min(...magicValues)
|
|
99
|
+
|
|
100
|
+
// Get the highest/lowest physical value
|
|
101
|
+
const physicalValues = gotchis.map(gotchi => gotchi.physical)
|
|
102
|
+
const highestPhysical = Math.max(...physicalValues)
|
|
103
|
+
const lowestPhysical = Math.min(...physicalValues)
|
|
104
|
+
|
|
105
|
+
// If this is a magic gotchi then set the magic value to the highest
|
|
106
|
+
if (brainValue === 'magic') {
|
|
107
|
+
avgGotchi.magic = highestMagic
|
|
108
|
+
avgGotchi.physical = lowestPhysical
|
|
109
|
+
avgGotchi.attack = 'magic'
|
|
110
|
+
} else {
|
|
111
|
+
avgGotchi.magic = lowestMagic
|
|
112
|
+
avgGotchi.physical = highestPhysical
|
|
113
|
+
avgGotchi.attack = 'physical'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
avgGotchis.push(avgGotchi)
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
trainingGotchis.push(...avgGotchis)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Sort the gotchis by id
|
|
125
|
+
trainingGotchis.sort((a, b) => a.id - b.id)
|
|
126
|
+
|
|
127
|
+
trainingGotchis.forEach(gotchi => {
|
|
128
|
+
// Add special to gotchi
|
|
129
|
+
const special = specials.find(special => special.id === gotchi.specialId)
|
|
130
|
+
|
|
131
|
+
if (!special) throw new Error(`Special not found for gotchi: "${gotchi.name}"`)
|
|
132
|
+
|
|
133
|
+
gotchi.special = special
|
|
134
|
+
|
|
135
|
+
// Fix names
|
|
136
|
+
// If name ends with a + or - then add the class name at the end
|
|
137
|
+
if (gotchi.name.endsWith('+') || gotchi.name.endsWith('-')) {
|
|
138
|
+
gotchi.name = `${gotchi.name} ${classes[gotchi.specialId - 1]}`
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Remove extra fields
|
|
142
|
+
delete gotchi.tier
|
|
143
|
+
delete gotchi.class
|
|
144
|
+
delete gotchi.stats_brs
|
|
145
|
+
|
|
146
|
+
// Make sure the gotchi has the correct traits
|
|
147
|
+
mapGotchi(gotchi)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// Add the average gotchis
|
|
151
|
+
addAvgGotchs()
|
|
152
|
+
|
|
153
|
+
// Write the updated trainingGotchis to a new file
|
|
154
|
+
fs.writeFileSync('./training_gotchis1.json', JSON.stringify(trainingGotchis, null, '\t'))
|
|
155
|
+
|
|
260
156
|
// node scripts/balancing/fixTrainingGotchis.js
|