gotchi-battler-game-logic 1.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.
@@ -0,0 +1,5 @@
1
+ {
2
+ "files.exclude": {
3
+ "**/.git": false
4
+ }
5
+ }
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Galaxy Brain Studios - Gotchi Battler Game Logic
2
+
3
+ This npm module contains the game logic for the Gotchi Battler game developed by Galaxy Brain Studios.
4
+
5
+ ## Installation
6
+
7
+ To install the module, run the following command:
8
+
9
+ ```
10
+ npm install gotchi-battler-game-logic
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ To use the module in your project, import it as follows:
16
+
17
+ ```javascript
18
+ const game = require('gotchi-battler-game-logic')
19
+
20
+ // team1 and team2 an in-game team objects (see below)
21
+ // seed is a random seed for the game
22
+ const result = game(team1, team2, seed)
23
+ ```
24
+ The schema for the in-game team object can be found in `/schemas/team.json`
25
+
26
+ Examples of the in-game team object can be found in `/scripts/data/team1.json` and `/scripts/data/team2.json`
27
+
28
+ ## Development
29
+
30
+ ### Validate Tournament
31
+
32
+ The validate tournament script does the following:
33
+ - Fetches the data of a tournament from the Gotchi Battler website
34
+ - Loops through all the battles in the tournament, bracket by bracket, round by round
35
+ - For each battle, the logs are fetched from the Gotchi Battler website
36
+ - The battle is then simulated using the game logic
37
+ - The result of the simulation is compared to the actual result of the battle
38
+
39
+ To validate the battles from the RF8 100K Tournament, run the following command:
40
+
41
+ ```bash
42
+ node scripts/validateTournament.js 15
43
+ ```
44
+
45
+ Get the tournament id from the URL of the tournament page on the Gotchi Battler website.
46
+
47
+
48
+ PLEASE NOTE:
49
+ - Currently, only the tournaments from Rarity Farming season 8 are supported (Tournament IDs 13-15)
50
+ - The script can take a while to run, in local testing it took around 20 minutes
@@ -0,0 +1,209 @@
1
+ [
2
+ {
3
+ "inputs": [
4
+ {
5
+ "internalType": "uint64",
6
+ "name": "subscriptionId",
7
+ "type": "uint64"
8
+ },
9
+ {
10
+ "internalType": "address",
11
+ "name": "vrfCoordinator",
12
+ "type": "address"
13
+ },
14
+ {
15
+ "internalType": "address",
16
+ "name": "link",
17
+ "type": "address"
18
+ },
19
+ {
20
+ "internalType": "bytes32",
21
+ "name": "keyHash",
22
+ "type": "bytes32"
23
+ },
24
+ {
25
+ "internalType": "address",
26
+ "name": "feeTokenAddress",
27
+ "type": "address"
28
+ }
29
+ ],
30
+ "stateMutability": "nonpayable",
31
+ "type": "constructor"
32
+ },
33
+ {
34
+ "inputs": [
35
+ {
36
+ "internalType": "address",
37
+ "name": "have",
38
+ "type": "address"
39
+ },
40
+ {
41
+ "internalType": "address",
42
+ "name": "want",
43
+ "type": "address"
44
+ }
45
+ ],
46
+ "name": "OnlyCoordinatorCanFulfill",
47
+ "type": "error"
48
+ },
49
+ {
50
+ "anonymous": false,
51
+ "inputs": [
52
+ {
53
+ "indexed": false,
54
+ "internalType": "uint32",
55
+ "name": "roundNumber",
56
+ "type": "uint32"
57
+ },
58
+ {
59
+ "indexed": false,
60
+ "internalType": "uint256",
61
+ "name": "randomWords",
62
+ "type": "uint256"
63
+ }
64
+ ],
65
+ "name": "ReturnedRoundRandomness",
66
+ "type": "event"
67
+ },
68
+ {
69
+ "inputs": [
70
+ {
71
+ "internalType": "uint32",
72
+ "name": "askedRound",
73
+ "type": "uint32"
74
+ }
75
+ ],
76
+ "name": "askRoundSeed",
77
+ "outputs": [],
78
+ "stateMutability": "nonpayable",
79
+ "type": "function"
80
+ },
81
+ {
82
+ "inputs": [],
83
+ "name": "contractOwner",
84
+ "outputs": [
85
+ {
86
+ "internalType": "address",
87
+ "name": "",
88
+ "type": "address"
89
+ }
90
+ ],
91
+ "stateMutability": "view",
92
+ "type": "function"
93
+ },
94
+ {
95
+ "inputs": [],
96
+ "name": "invalidateTournament",
97
+ "outputs": [],
98
+ "stateMutability": "nonpayable",
99
+ "type": "function"
100
+ },
101
+ {
102
+ "inputs": [
103
+ {
104
+ "internalType": "uint32",
105
+ "name": "",
106
+ "type": "uint32"
107
+ }
108
+ ],
109
+ "name": "isRoundSeedRequested",
110
+ "outputs": [
111
+ {
112
+ "internalType": "bool",
113
+ "name": "",
114
+ "type": "bool"
115
+ }
116
+ ],
117
+ "stateMutability": "view",
118
+ "type": "function"
119
+ },
120
+ {
121
+ "inputs": [],
122
+ "name": "isValid",
123
+ "outputs": [
124
+ {
125
+ "internalType": "bool",
126
+ "name": "",
127
+ "type": "bool"
128
+ }
129
+ ],
130
+ "stateMutability": "view",
131
+ "type": "function"
132
+ },
133
+ {
134
+ "inputs": [
135
+ {
136
+ "internalType": "uint256",
137
+ "name": "requestId",
138
+ "type": "uint256"
139
+ },
140
+ {
141
+ "internalType": "uint256[]",
142
+ "name": "randomWords",
143
+ "type": "uint256[]"
144
+ }
145
+ ],
146
+ "name": "rawFulfillRandomWords",
147
+ "outputs": [],
148
+ "stateMutability": "nonpayable",
149
+ "type": "function"
150
+ },
151
+ {
152
+ "inputs": [],
153
+ "name": "roundNumber",
154
+ "outputs": [
155
+ {
156
+ "internalType": "uint32",
157
+ "name": "",
158
+ "type": "uint32"
159
+ }
160
+ ],
161
+ "stateMutability": "view",
162
+ "type": "function"
163
+ },
164
+ {
165
+ "inputs": [
166
+ {
167
+ "internalType": "uint32",
168
+ "name": "",
169
+ "type": "uint32"
170
+ }
171
+ ],
172
+ "name": "roundSeeds",
173
+ "outputs": [
174
+ {
175
+ "internalType": "uint256",
176
+ "name": "",
177
+ "type": "uint256"
178
+ }
179
+ ],
180
+ "stateMutability": "view",
181
+ "type": "function"
182
+ },
183
+ {
184
+ "inputs": [],
185
+ "name": "s_requestId",
186
+ "outputs": [
187
+ {
188
+ "internalType": "uint256",
189
+ "name": "",
190
+ "type": "uint256"
191
+ }
192
+ ],
193
+ "stateMutability": "view",
194
+ "type": "function"
195
+ },
196
+ {
197
+ "inputs": [
198
+ {
199
+ "internalType": "address",
200
+ "name": "_owner",
201
+ "type": "address"
202
+ }
203
+ ],
204
+ "name": "setOwner",
205
+ "outputs": [],
206
+ "stateMutability": "nonpayable",
207
+ "type": "function"
208
+ }
209
+ ]
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ 'v1.4': require('./v1.4'),
3
+ 'v1.5': require('./v1.5'),
4
+ 'v1.6': require('./v1.6'),
5
+ current: 'v1.6'
6
+ }
@@ -0,0 +1,121 @@
1
+ const PASSIVES = ['sharp_blades', 'cloud_of_zen', 'frenzy', 'fortify', 'spread_the_fear', 'cleansing_aura', 'channel_the_coven', 'clan_momentum']
2
+ const DEBUFF_STATUSES = ['bleed', 'stun']
3
+ const BUFF_STATUSES = ['taunt']
4
+
5
+ const BUFF_MULT_EFFECTS = {
6
+ power_up_1: {
7
+ magic: 0.125,
8
+ physical: 0.125
9
+ },
10
+ power_up_2: {
11
+ crit: 0.5,
12
+ magic: 0.425,
13
+ physical: 0.425
14
+ },
15
+ fortify: {
16
+ armor: 0.8
17
+ },
18
+ taunt: {
19
+ armor: 0.4
20
+ }
21
+ }
22
+
23
+ const BUFF_FLAT_EFFECTS = {
24
+ fortify: {
25
+ armor: 60
26
+ },
27
+ frenzy: {
28
+ crit: 16
29
+ }
30
+ }
31
+
32
+ // Combine all buffs
33
+ const BUFFS = [...PASSIVES, ...BUFF_STATUSES, ...Object.keys(BUFF_MULT_EFFECTS), ...Object.keys(BUFF_FLAT_EFFECTS)]
34
+
35
+ const DEBUFF_MULT_EFFECTS = {
36
+
37
+ }
38
+
39
+ const DEBUFF_FLAT_EFFECTS = {
40
+
41
+ }
42
+
43
+ // Combine all debuffs
44
+ const DEBUFFS = [...DEBUFF_STATUSES, ...Object.keys(DEBUFF_MULT_EFFECTS), ...Object.keys(DEBUFF_FLAT_EFFECTS)]
45
+
46
+ const MULTS = {
47
+ FRONT_ROW_PHY_ATK: 1.1,
48
+ FRONT_ROW_PHY_DEF: 0.9,
49
+ EXPIRE_LEADERSKILL: 0,
50
+ SPEED_PENALTY: 2.5,
51
+ MAX_STATUSES: 3,
52
+ CRIT_MULTIPLIER_FAST: 1.8,
53
+ CRIT_MULTIPLIER_SLOW: 1.8,
54
+ FORTIFY_COUNTER_CHANCE: 20,
55
+ COUNTER_CHANCE_MIN: 10,
56
+ COUNTER_DAMAGE: 1.2,
57
+ SHARP_BLADES_BLEED_CHANCE: 0.8,
58
+ BLEED_DAMAGE: 7,
59
+ SPECTRAL_STRIKE_DAMAGE: 1.4,
60
+ CLEAVE_DAMAGE: 0.9,
61
+ CURSE_DAMAGE: 1.5,
62
+ CURSE_SPEED_PENALTY: 0,
63
+ SPREAD_THE_FEAR_CHANCE: 0.9,
64
+ SPREAD_THE_FEAR_SPEED_PENALTY: 0.4,
65
+ BLESSING_HEAL: 4,
66
+ BLESSING_HEAL_SPEED_PENALTY: 0,
67
+ CLEANSING_AURA_HEAL: 6,
68
+ BLESSING_HEAL_CRIT_MULTIPLIER: 1.5,
69
+ CLEANSING_AURA_REGEN: 0.75,
70
+ CLEANSING_AURA_NON_HEALER_REGEN: 7,
71
+ THUNDER_DAMAGE_SLOW: 0.65,
72
+ THUNDER_DAMAGE_FAST: 0.65,
73
+ CHANNEL_THE_COVEN_DAMAGE_SLOW: 0.65,
74
+ CHANNEL_THE_COVEN_DAMAGE_FAST: 0.45,
75
+ DEVESTATING_SMASH_DAMAGE: 2.4,
76
+ DEVESTATING_SMASH_SPEED_PENALTY: 2.5,
77
+ CLAN_MOMENTUM_DAMAGE: 2.5
78
+ }
79
+
80
+ const passiveIcons = {
81
+ 'sharp_blades': 'https://game-icons.net/1x1/lorc/plain-dagger.html',
82
+ 'cloud_of_zen': 'https://game-icons.net/1x1/lorc/meditation.html',
83
+ 'frenzy': 'https://game-icons.net/1x1/lorc/totem-head.html',
84
+ 'fortify': 'https://game-icons.net/1x1/lorc/crenulated-shield.html',
85
+ 'spread_the_fear': 'https://game-icons.net/1x1/lorc/evil-book.html',
86
+ 'cleansing_aura': 'https://game-icons.net/1x1/lorc/aura.html',
87
+ 'channel_the_coven': 'https://game-icons.net/1x1/lorc/witch-flight.html',
88
+ 'clan_momentum': 'https://game-icons.net/1x1/delapouite/bully-minion.html'
89
+ }
90
+
91
+ const debuffIcons = {
92
+ 'bleed': 'https://game-icons.net/1x1/lorc/broken-heart.html',
93
+ 'stun': 'https://game-icons.net/1x1/sbed/electric.html',
94
+ 'fear': 'https://game-icons.net/1x1/lorc/screaming.html'
95
+ }
96
+
97
+ const buffIcons = {
98
+ 'taunt': 'https://game-icons.net/1x1/lorc/archery-target.html',
99
+ 'power_up_1': 'https://game-icons.net/1x1/lorc/strong.html',
100
+ 'power_up_2': 'https://game-icons.net/1x1/delapouite/mighty-force.html'
101
+ }
102
+
103
+ module.exports = {
104
+ PASSIVES,
105
+ DEBUFF_STATUSES,
106
+ BUFF_STATUSES,
107
+ BUFF_MULT_EFFECTS,
108
+ BUFF_FLAT_EFFECTS,
109
+ BUFFS,
110
+ DEBUFF_MULT_EFFECTS,
111
+ DEBUFF_FLAT_EFFECTS,
112
+ DEBUFFS,
113
+ MULTS
114
+ }
115
+
116
+ // node services/game-logic/constants.js
117
+ if (require.main === module) {
118
+ console.log("Buffs", BUFFS)
119
+ console.log("Debuffs", DEBUFFS)
120
+ process.exit(0)
121
+ }