Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of a thread from Glitch City Laboratories Forums.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of this forum in .tar.gz, .sql.gz, or .sqlite.gz formats.

Emulation & ROM Hacking

Spaceworld Demo Datamining - Page 1

Spaceworld Demo Datamining

Posted by: OldNewComputers
Date: 2019-01-23 16:16:16
Based on a small datamining tool I wrote for Generation 1, I adapted it to the Spaceworld demo based on some Gen II base stats info from Bulbapedia. I attached a CSV (well, not sure how to attach a file so I just inserted it as code) with the base stats info I've gotten out of the ROM. (No idea if this is the right place to put this topic). While I found tons of stuff on the sprites from the Gen 2 beta, I didn't find the basestats anywhere. Now, here is what I learned about the Pokemon Base Stats data structure from the Gen 2 betas. I've only attached the new Pokemon and I'll also insert the program code.

- Bulbasaur begins at 0x50f10
- The format is largely the same as Generation II
- Each Pokemon is 31 bytes long, instead of 32 bytes like the final game (not sure what is cut out yet, may be egg info or one of the TM flag bytes)

#, HP, ATK, DEF, SPD, SPATK, SPDEF, TYPE1, TYPE2, CATCHRATE, BASEEXP, GENDER
152, 55, 40, 45, 40, 75, 50, GRASS, GRASS, 255, 64, MEDIUM SLOW, 50/50 M/F
153, 50, 45, 50, 50, 45, 50, GRASS, GRASS, 255, 100, MEDIUM SLOW, 50/50 M/F
154, 70, 65, 60, 60, 55, 50, GRASS, GRASS, 255, 100, MEDIUM SLOW, 50/50 M/F
155, 50, 60, 40, 40, 50, 50, FIRE, FIRE, 255, 64, MEDIUM SLOW, 50/50 M/F
156, 60, 70, 50, 50, 60, 50, FIRE, FIRE, 255, 100, MEDIUM SLOW, 50/50 M/F
157, 70, 80, 60, 60, 70, 50, FIRE, FIRE, 255, 100, MEDIUM SLOW, 50/50 M/F
158, 45, 50, 50, 45, 50, 50, WATER, WATER, 255, 64, MEDIUM SLOW, 50/50 M/F
159, 55, 55, 60, 55, 55, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
160, 75, 60, 70, 65, 60, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
161, 65, 55, 40, 65, 55, 50, FLYING, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
162, 50, 50, 50, 50, 50, 50, FLYING, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
163, 50, 50, 50, 50, 50, 50, ELECTRIC, ELECTRIC, 255, 100, MEDIUM SLOW, 50/50 M/F
164, 50, 50, 50, 50, 50, 50, ELECTRIC, ELECTRIC, 255, 100, MEDIUM SLOW, 50/50 M/F
165, 55, 45, 45, 50, 70, 50, ELECTRIC, ELECTRIC, 255, 100, MEDIUM SLOW, 50/50 M/F
166, 50, 50, 50, 50, 50, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
167, 50, 50, 50, 50, 50, 50, GRASS, GRASS, 255, 100, MEDIUM SLOW, 50/50 M/F
168, 50, 50, 50, 50, 50, 50, GRASS, GRASS, 255, 100, MEDIUM SLOW, 50/50 M/F
169, 50, 50, 50, 50, 50, 50, WATER, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
170, 55, 80, 50, 45, 60, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
171, 50, 50, 50, 50, 50, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
172, 50, 50, 50, 50, 50, 50, ELECTRIC, ELECTRIC, 255, 100, MEDIUM SLOW, 50/50 M/F
173, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
174, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
175, 50, 45, 50, 55, 75, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
176, 45, 50, 50, 60, 50, 50, FLYING, PSYCHIC, 255, 100, MEDIUM SLOW, 50/50 M/F
177, 55, 50, 50, 80, 70, 50, FLYING, PSYCHIC, 255, 100, MEDIUM SLOW, 50/50 M/F
178, 50, 50, 50, 50, 50, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
179, 45, 50, 55, 40, 55, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
180, 50, 50, 50, 30, 50, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
181, 90, 110, 50, 110, 55, 50, WATER, STEEL, 255, 100, MEDIUM SLOW, 50/50 M/F
182, 60, 65, 60, 30, 80, 50, WATER, STEEL, 255, 100, MEDIUM SLOW, 50/50 M/F
183, 60, 65, 50, 85, 45, 50, POISON, FLYING, 255, 100, MEDIUM FAST, 50/50 M/F
184, 50, 50, 50, 50, 50, 50, BUG, GRASS, 255, 100, MEDIUM SLOW, 50/50 M/F
185, 50, 50, 50, 50, 50, 50, BUG, POISON, 255, 100, MEDIUM SLOW, 50/50 M/F
186, 50, 50, 50, 50, 50, 50, BUG, POISON, 255, 100, MEDIUM SLOW, 50/50 M/F
187, 50, 50, 50, 50, 50, 50, FLYING, STEEL, 255, 100, MEDIUM SLOW, 50/50 M/F
188, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
189, 50, 50, 50, 50, 50, 50, NORMAL, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
190, 50, 50, 50, 50, 50, 50, GRASS, PSYCHIC, 255, 100, MEDIUM SLOW, 50/50 M/F
191, 50, 50, 50, 50, 50, 50, GROUND, GROUND, 255, 100, MEDIUM SLOW, 50/50 M/F
192, 70, 70, 70, 50, 50, 50, GROUND, GROUND, 255, 100, MEDIUM SLOW, 50/50 M/F
193, 50, 50, 50, 50, 50, 50, DARK, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
194, 70, 50, 50, 45, 45, 50, DARK, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
195, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
196, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
197, 40, 65, 40, 70, 65, 50, DARK, DARK, 255, 100, MEDIUM SLOW, 100% Female
198, 50, 50, 50, 50, 50, 50, DARK, DARK, 255, 100, MEDIUM SLOW, 50/50 M/F
199, 90, 85, 95, 70, 70, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
200, 95, 75, 110, 30, 80, 50, WATER, PSYCHIC, 255, 100, MEDIUM FAST, 50/50 M/F
201, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
202, 50, 50, 50, 50, 50, 50, BUG, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
203, 50, 50, 50, 50, 50, 50, BUG, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
204, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
205, 50, 50, 50, 50, 50, 50, PSYCHIC, PSYCHIC, 255, 100, MEDIUM SLOW, 50/50 M/F
206, 50, 50, 50, 50, 50, 50, POISON, POISON, 255, 100, MEDIUM SLOW, 50/50 M/F
207, 50, 50, 50, 50, 50, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
208, 50, 50, 50, 50, 50, 50, POISON, POISON, 255, 100, MEDIUM SLOW, 50/50 M/F
209, 50, 50, 50, 50, 50, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
210, 50, 50, 50, 50, 50, 50, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
211, 50, 50, 50, 50, 50, 50, FIGHTING, FIGHTING, 255, 100, MEDIUM SLOW, 50/50 M/F
212, 50, 50, 50, 50, 50, 50, FIGHTING, FIGHTING, 255, 100, MEDIUM SLOW, 50/50 M/F
213, 50, 50, 50, 50, 50, 50, FIRE, FIRE, 255, 100, MEDIUM SLOW, 50/50 M/F
214, 40, 50, 35, 50, 50, 50, GRASS, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
215, 50, 50, 45, 50, 60, 50, GRASS, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
216, 60, 50, 55, 50, 70, 50, GRASS, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
217, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
218, 50, 50, 50, 50, 50, 50, ICE, ICE, 255, 100, MEDIUM SLOW, 50/50 M/F
219, 30, 55, 45, 65, 50, 50, ELECTRIC, ELECTRIC, 255, 100, MEDIUM FAST, 100% Male
220, 50, 50, 50, 50, 50, 50, FIRE, FIRE, 255, 100, MEDIUM SLOW, 50/50 M/F
221, 50, 50, 50, 50, 50, 50, GRASS, POISON, 255, 100, MEDIUM SLOW, 50/50 M/F
222, 50, 50, 50, 50, 50, 50, GRASS, POISON, 255, 100, MEDIUM SLOW, 50/50 M/F
223, 110, 50, 60, 40, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
224, 50, 50, 50, 50, 50, 50, WATER, FIRE, 255, 100, MEDIUM SLOW, 50/50 M/F
225, 50, 50, 50, 50, 50, 50, WATER, ICE, 255, 100, MEDIUM SLOW, 50/50 M/F
226, 55, 50, 45, 50, 50, 50, ELECTRIC, ELECTRIC, 255, 100, MEDIUM SLOW, 50/50 M/F
227, 65, 60, 55, 60, 60, 50, ELECTRIC, ELECTRIC, 255, 100, MEDIUM SLOW, 50/50 M/F
228, 50, 50, 50, 50, 50, 50, NORMAL, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
229, 55, 40, 50, 45, 75, 50, GHOST, GHOST, 255, 100, MEDIUM SLOW, 50/50 M/F
230, 60, 50, 55, 55, 70, 50, GHOST, GHOST, 255, 100, MEDIUM SLOW, 50/50 M/F
231, 50, 50, 50, 50, 50, 50, DARK, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
232, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
233, 50, 50, 50, 50, 50, 50, BUG, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
234, 50, 50, 50, 50, 50, 50, BUG, BUG, 255, 100, MEDIUM SLOW, 50/50 M/F
235, 50, 50, 50, 50, 50, 50, FIRE, FIRE, 255, 100, MEDIUM SLOW, 50/50 M/F
236, 50, 50, 50, 50, 50, 50, FIRE, FIRE, 255, 100, MEDIUM SLOW, 50/50 M/F
237, 50, 50, 50, 50, 50, 50, ICE, ICE, 255, 100, MEDIUM SLOW, 50/50 M/F
238, 50, 50, 50, 50, 50, 50, ICE, ICE, 255, 100, MEDIUM SLOW, 50/50 M/F
239, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
240, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
241, 50, 50, 50, 50, 50, 50, STEEL, GROUND, 255, 100, MEDIUM SLOW, 50/50 M/F
242, 50, 50, 50, 50, 50, 50, DRAGON, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
243, 90, 90, 85, 100, 125, 98, ELECTRIC, ELECTRIC, 255, 100, MEDIUM SLOW, 50/50 M/F
244, 90, 100, 90, 90, 125, 99, FIRE, FIRE, 255, 100, MEDIUM SLOW, 50/50 M/F
245, 90, 85, 100, 85, 125, 97, WATER, WATER, 255, 100, MEDIUM SLOW, 50/50 M/F
246, 45, 65, 50, 85, 40, 50, DARK, DARK, 255, 100, MEDIUM SLOW, 50/50 M/F
247, 100, 100, 100, 100, 100, 50, FLYING, FLYING, 255, 100, MEDIUM SLOW, 50/50 M/F
248, 50, 50, 50, 50, 50, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
249, 65, 70, 60, 50, 70, 50, PSYCHIC, PSYCHIC, 255, 100, MEDIUM SLOW, 100% Female
250, 55, 55, 50, 60, 60, 50, NORMAL, NORMAL, 255, 100, MEDIUM SLOW, 50/50 M/F
251, 50, 50, 50, 50, 50, 50, GRASS, GRASS, 255, 100, MEDIUM SLOW, 50/50 M/F


#constants
FILE_NAME = "pkmn_gold.sgb"
FILE = open(FILE_NAME, "rb")
FILE_CONTENTS = FILE.read()
FILE.close()

typeDict = {0: "NORMAL", 1: "FIGHTING", 2: "FLYING", 3: "POISON", 4: "GROUND",
            5: "ROCK", 6: "BIRD", 7: "BUG", 8: "GHOST", 9: "STEEL", 0x14: "FIRE",
            0x15: "WATER", 0x16: "GRASS", 0x17: "ELECTRIC", 0x18:"PSYCHIC",
            0x19: "ICE", 0x1A: "DRAGON", 0x1B: "DARK"}


growthDict = {0: "MEDIUM FAST", 3: "MEDIUM SLOW", 4: "FAST", 5: "SLOW"}


#loop 45 49
"""for i in range(len(FILE_CONTENTS)):
  if FILE_CONTENTS[i] == 1 and FILE_CONTENTS[i+1] == 45 and FILE_CONTENTS[i+2] == 49:
    print(i)"""

#functions
def findBulba():
  for i in range(len(FILE_CONTENTS)):
    if FILE_CONTENTS[i] == 1 and FILE_CONTENTS[i+1] == 45 and FILE_CONTENTS[i+2] == 49:
      return i

def findIvy():
  for i in range(len(FILE_CONTENTS)):
    if FILE_CONTENTS[i] == 2 and FILE_CONTENTS[i+1] == 60 and FILE_CONTENTS[i+2] == 62:
      return i

def offsetCalc(pokedexNum):
  return 331536 + (31 * (pokedexNum - 1))

def printPkmn(pokedexNum): #gender is 0x0d
  offset = offsetCalc(pokedexNum)
  print("Pokedex #: {}".format(FILE_CONTENTS[offset]))

  print("Base HP: {}".format(FILE_CONTENTS[offset+1]))

  print("Base Attack: {}".format(FILE_CONTENTS[offset+2]))

  print("Base Defense: {}".format(FILE_CONTENTS[offset+3]))

  print("Base Speed: {}".format(FILE_CONTENTS[offset+4]))

  print("Base SpAtk: {}".format(FILE_CONTENTS[offset+5]))

  print("Base SpDef: {}".format(FILE_CONTENTS[offset+6]))

  print("Type 1: {}".format(typeDict[FILE_CONTENTS[offset+7]]))

  print("Type 2: {}".format(typeDict[FILE_CONTENTS[offset+8]]))

  print("Catch Rate: {}".format(FILE_CONTENTS[offset+9]))

  print("Base EXP Yield: {}".format(FILE_CONTENTS[offset+10]))

  if FILE_CONTENTS[offset+0xd] == 255:
    gender = "100% Genderless"
 
  if FILE_CONTENTS[offset+0xd] == 254:
    gender = "100% Female"
 
  if FILE_CONTENTS[offset+0xd] == 191:
    gender = "25%M/75%F"
 
  if FILE_CONTENTS[offset+0xd] == 127:
    gender = "50/50 M/F"
 
  if FILE_CONTENTS[offset+0xd] == 63:
    gender = "75M/25F"
 
  if FILE_CONTENTS[offset+0xd] == 31:
    gender = "87.5M/12.5F"
 
  if FILE_CONTENTS[offset+0xd] == 0:
    gender = "100% Male"
 
  print("Growth Rate: {}".format(growthDict[FILE_CONTENTS[offset+0x16]]))

  print("Gender Ratio: {}".format(gender))

def genCSVLine(pokedexNum): #gender is 0x0d
  CSVLine = ""
  offset = offsetCalc(pokedexNum)
  #print("Pokedex #: {}".format(FILE_CONTENTS[offset]))
  CSVLine += str(FILE_CONTENTS[offset]) + ", "

  #print("Base HP: {}".format(FILE_CONTENTS[offset+1]))
  CSVLine += str(FILE_CONTENTS[offset+1]) + ", "

  #print("Base Attack: {}".format(FILE_CONTENTS[offset+2]))
  CSVLine += str(FILE_CONTENTS[offset+2]) + ", "

  #print("Base Defense: {}".format(FILE_CONTENTS[offset+3]))
  CSVLine += str(FILE_CONTENTS[offset+3]) + ", "

  #print("Base Speed: {}".format(FILE_CONTENTS[offset+4]))
  CSVLine += str(FILE_CONTENTS[offset+4]) + ", "

  #print("Base SpAtk: {}".format(FILE_CONTENTS[offset+5]))
  CSVLine += str(FILE_CONTENTS[offset+5]) + ", "

  #print("Base SpDef: {}".format(FILE_CONTENTS[offset+6]))
  CSVLine += str(FILE_CONTENTS[offset+6]) + ", "

  #print("Type 1: {}".format(typeDict[FILE_CONTENTS[offset+7]]))
  CSVLine += str(typeDict[FILE_CONTENTS[offset+7]]) + ", "

  #print("Type 2: {}".format(typeDict[FILE_CONTENTS[offset+8]]))
  CSVLine += str(typeDict[FILE_CONTENTS[offset+8]]) + ", "

  #print("Catch Rate: {}".format(FILE_CONTENTS[offset+9]))
  CSVLine += str(FILE_CONTENTS[offset+9]) + ", "

  #print("Base EXP Yield: {}".format(FILE_CONTENTS[offset+10]))
  CSVLine += str(FILE_CONTENTS[offset+10]) + ", "

  if FILE_CONTENTS[offset+0xd] == 255:
    gender = "100% Genderless"
 
  if FILE_CONTENTS[offset+0xd] == 254:
    gender = "100% Female"
 
  if FILE_CONTENTS[offset+0xd] == 191:
    gender = "25%M/75%F"
 
  if FILE_CONTENTS[offset+0xd] == 127:
    gender = "50/50 M/F"
 
  if FILE_CONTENTS[offset+0xd] == 63:
    gender = "75M/25F"
 
  if FILE_CONTENTS[offset+0xd] == 31:
    gender = "87.5M/12.5F"
 
  if FILE_CONTENTS[offset+0xd] == 0:
    gender = "100% Male"
 
  #print("Growth Rate: {}".format(growthDict[FILE_CONTENTS[offset+0x16]]))
  CSVLine += growthDict[FILE_CONTENTS[offset+0x16]] + ", "

  #print("Gender Ratio: {}".format(gender))
  CSVLine += gender
  return CSVLine

def genCSV():
  CSV = "#, HP, ATK, DEF, SPD, SPATK, SPDEF, TYPE1, TYPE2, CATCHRATE, BASEEXP, GENDER\n"
  for i in range(152, 252):
    CSV += genCSVLine(i) + "\n"
  print(CSV)
  return

Re: Spaceworld Demo Datamining

Posted by: Sherkel
Date: 2019-01-23 16:26:49
As with your previous program, it doesn't provide anything new, but seems like it was a good coding exercise that could be adapted for a good few necessary scripts in the future. :)

Re: Spaceworld Demo Datamining

Posted by: OldNewComputers
Date: 2019-01-23 16:57:27

As with your previous program, it doesn't provide anything new, but seems like it was a good coding exercise that could be adapted for a good few necessary scripts in the future. :)


Thanks for your input, you do have a point that the basestats data is found elsewhere and so is the general program, but what necessary scripts are you potentially referring to?

Re: Spaceworld Demo Datamining

Posted by: Sherkel
Date: 2019-01-23 17:22:46
I don't know what they might end up being. I'm just saying it's good to have another technically-minded member interested in contributing.