When this page first created/started, I wasn't aware of the existence of speedrun.com (which was founded in 2014).
I still find this page useful but it could be improved upon. Since speedrun.com let's you filter on the site (but you can't get a list of games with a run), the API could be used to get that list.
Before jumping right in, I first examine a good workflow for all this:
I will need to:
- Write down dates of dumps (to make updates easier)
Useful links to be used:
-
Wiki: Game/all
- All platforms (119 at the moment)
https://www.speedrun.com/api/v1/platforms?offset=0&max=200
- Get all runs from <platform> (without game informations, we get the IDs only). For 3DO platform:
https://www.speedrun.com/api/v1/runs?platform=8gejmne3offset=0&max=200
https://www.speedrun.com/api/v1/runs?platform=8gejmne3offset=200&max=200
https://www.speedrun.com/api/v1/runs?platform=8gejmne3offset=400&max=200
- With game informations + orderby (not sure how it orders) + direction
https://www.speedrun.com/api/v1/runs?platform=8gejmne3offset=0&max=200&embed=game&orderby=game&direction=asc
With the above link I've made a Python script.
- Requests the speedrun.com API when it needs to.
- Date (time of running the script) is not implemented. Will be added to the right requests in to the parameters to get only the "new" things to update.
- GetLevel (for getting relevant info of single level runs) are not implemented (as TASVideos not accepts single level runs)
- For whatever reasons, I don't find the full category names as listed on the page of the run. Relevant API doc
https://github.com/speedruncomorg/api/blob/master/version1/categories.md
edit3: Updated code
- outputs in table format in the same vein as SDATASes
- will put it to a new page when done, because of different timing than SDA, timings vary game by game and category and generally the rule difference between the two
Language: python
import requests, time
date = r"2019-01-11T12:03:22Z"
"""
- Requests the speedrun.com API when it needs to.
- Date (time of running the script) is not implemented.
Will be added to the right requests in to the parameters to get only the "new" things to update.
- For whatever reasons, I don't find the full category names as listed on the page of the run.
Relevant API doc https://github.com/speedruncomorg/api/blob/master/version1/categories.md
"""
def GetPlatforms():
"""
API pagination limit: 200
"""
gets = 0
offset = 0
parameters = {"max": 200, "offset": offset}
next = True
while next:
r = requests.get("https://www.speedrun.com/api/v1/platforms", params=parameters, timeout=60)
gets += 1
if r.status_code == requests.codes.ok:
for platform in r.json()['data']:
print(r"%%%TAB {}%%%\n||Game||Information||".format(platform['name']))
GetRuns(platform['id'])
if r.json()['pagination']['size'] == 200:
offset += 200
else:
next = False
else: time.sleep(30)
return gets
def GetRuns(id):
"""
API pagination limit: 200
"""
gets = 0
gamegoal = {}
runs = {}
offset = 0
parameters = {"embed": "game", "orderby": "submitted", "direction": "desc", "max": 200, "offset": offset, "platform": id}
next = True
while next:
r = requests.get("https://www.speedrun.com/api/v1/runs", params=parameters, timeout=60)
gets += 1
if r.status_code == requests.codes.ok:
for run in r.json()['data']:
time = 0
if run['times']['ingame_t'] != 0:
time = run['times']['ingame_t']
if run['times']['realtime_t'] != 0:
time = run['times']['realtime_t']
if run['times']['primary_t'] != 0:
time = run['times']['primary_t']
gg = "{} {}".format(run['game']['data']['names']['international'], run['category'])
if gg in gamegoal:
if time < gamegoal[gg]:
gamegoal[gg] = time
runs[gg] = "|[{}|{} \"{}\"] in [module:frames|amount={}|fps=1]||".format(run['weblink'], run['game']['data']['names']['international'], GetCategory(run['category']), time)
else:
gamegoal[gg] = time
runs[gg] = "|[{}|{} \"{}\"] in [module:frames|amount={}|fps=1]||".format(run['weblink'], run['game']['data']['names']['international'],GetCategory(run['category']), time)
# print("gets: {} - runs[gg]: {}".format(gets, runs[gg]))
gets += 1
if r.json()['pagination']['size'] == 200:
offset += 200
else:
next = False
else:
print("sleeping!")
time.sleep(30)
# runs = sorted(runs)
for run in sorted(runs):
print("{}".format(runs[run]))
return gets
def GetCategory(id):
r = requests.get("https://www.speedrun.com/api/v1/categories/" + id, timeout=60)
if r.status_code == requests.codes.ok:
if r.json()['data']['type'] == "per-level":
return "{} (single level)".format(r.json()['data']['name'])
else:
return r.json()['data']['name']
# print("GetPlatforms() - Number of GETs: {}".format(GetPlatforms()))
# print("GetRuns(\"w89rwwel\") - Number of GETs: {}".format(GetRuns("w89rwwel")))
# print("GetRuns(\"w89ryw6l\") - Number of GETs: {}".format(GetRuns("w89ryw6l")))
# ZX Spectrum
print("GetRuns(\"n568zo6v\") - Number of GETs: {}".format(GetRuns("n568zo6v")))
Outdated:
The only caveat so far is that runs can be invalid (cheated runs) and sometimes platform isn't filled in, but that's the most straightforward request I found possible so far.
edit: and it's also just threws GoldenEyes... looking for help on their discord channel.
https://www.speedrun.com/api/v1/runs?platform=arcade&embed=game
The other way would be using the website but it won't restrict runs to platforms:
https://www.speedrun.com/games#platform=Arcade&sorting=runCount&direction_sort=on