zengm
zengm copied to clipboard
Top 100 Players Pyramid
Note: This is my first attempt to contribute to the basketball-gm code. I don't reasonably expect this to be merged into production, but I created it as an experiment, and to get some feedback from dumbmatter and other developers
SUMMARY
Add a page ranking the top 100 players in the league's history, similar to Bill Simmons' Book of Basketball pyramid
OVERVIEW
- Add an attribute to the player type to track pyramid score ('hofScore') -- note: this functionality could be implemented without adding to a data type, but that was the first implementation I put together
- Refactor HOF calculation into a score calculator that returns a number, plus a bool that returns whether that number is > 100
- Add view for Pyramid page
- Update the league wrapper and column builder
- Add Pyramid score to player page
- Add logic to recalculate pyramid score each offseaseon
ISSUES
- Early on, there's lots of bad/meaningless data, including lots of negative scores, though these could easily be masked as 0.
- Currently saved as data when it could be calculated on the fly.
A few comments:
- I actually kind of like the HoF function refactor. Conceptually, we could use this in the future to answer questions like "if this player retired right now, would they make the HoF?" For example, let's say we added end-of-season recaps. We could actually say "future-Hall-of-Famer John Smith won his second championship" or something similar in the notifications.
- what does the Pyramid view accomplish, which the HoF page could not?
- attempting to answer that question myself, it seems like a "live look" at the league - you can weigh active players against HoF players. My next question is: could this have been integrated into the HoF page instead of making it a separate page? Look at how many lines of code are in the huge return in your players filter. Any patch we make to the HoF page would need to be mirrored to this page too. A unified page would be better, in my opinion.
Oh also I think Pyramid size should dynamically scale. We don't need Top 100 in the first five seasons and Top 100 probably wouldn't be enough after five hundred seasons.
@kgilbert-cmu Yeah, re: your first bullet, I was thinking that on the player page, you could have something like:
- if you're active, give a descriptor of the HoF credentials, like "Lock" if they're >100, "Borderline" if they're >90, etc.
- if they're retired but not in the HoF, don't show anything
- if they're retired and in the HoF, display the HoF score or something
@kgilbert-cmu Re your second and third bullet points... I did think about that. Could just display the stat of "HoF Score" on the HoF page as a starting point. But I considered it in the context of real NBA, and also how I play BBGM, and thought that it would be cool to see how active players fit in. But, as you said, you could probably just include that in HoF page too, with some sort of "projected HoFers" or something.
Mostly, I really like the idea of a page that adds some drama to the stats -- a curated page, as opposed to the HoF library of every great player. I was even thinking, on this page, of scrubbing most of the stats on the stats on the page and replacing them with "legacy" stats like Titles, MVPs, FMVPs, etc. I also had a vision of eventually logic that examines the player's career and sums it up in a phrase, like "All-around offensive genius" or "Defensive titan that brought 5 rings to NYC" or sometihng like that.
Anyways, thanks for the feedback! I'm going to clean a few things up when I have some time, and I'll ping you on discord. Hoping to get some feedback from others too
@kgilbert-cmu Oh and your idea of dynamically scaling -- something like 5 players a year until it hits a 100? I like that idea, I might try to add that. It cleans out the ugly data at the start of the league.
Thanks for the PR! Please take a look at this and make sure you're okay with it. If so, follow the instructions there. If not, I understand.
Could just display the stat of "HoF Score" on the HoF page as a starting point. But I considered it in the context of real NBA, and also how I play BBGM, and thought that it would be cool to see how active players fit in. But, as you said, you could probably just include that in HoF page too, with some sort of "projected HoFers" or something.
I would like that better.
I do see what you're saying about making it more accomplishment-based than stats-based... but stats do matter too. Maybe both could be satisfied by redesigning the HoF page.
I'm saying it shouldn't cap at 100 at all. I think it should start slowly, ramp up, peak speed around 20 or 50 players, slow down til 100, then have a (very) long tail after that.
Problem is: most leagues are very young and nascent. That messes with my estimates a lot, but let's assume that most players will play a league until it's 30+ seasons old before starting over.
Let's say we add 2-4-6-8-10-20 players at a time every 5 years which gets you a Top 20 after 20 seasons, and Top 50 after 30 seasons. Then adding 25 players every 10 years gets you to Top 100 after 50 seasons. After that, I'd add a tiny trickle. Something like 10 players every decade until you get to 200, then 5 players every decade until 500, then 1 player every decade forever.
That's an extremely long tail, but the idea is there. Just scratching out the math, you'd play several thousand seasons before you reach the end.
This is what that proposal would look like:
Year 0: league starts Year 5: top 2 Year 10: top 6 Year 15: top 12 Year 20: top 20 Year 25: top 30 Year 30: top 50 Year 40: top 75 Year 50: top 100 ... Year 60: top 110 Year 70: top 120 Year 80: top 130 (seven decades later) Year 150: top 200 ... Year 160: top 205 Year 170: top 210 (eight decades later) Year 250: top 250 (fifty decades later) Year 750: top 500 ... (five hundred decades later) Year 5750: top 1000
Feel free to tweak. I think the ramp down after Top 200 can be lowered even more. I smoothed it to make the numbers work cleanly for the "milestone years" when you get your Top 25, Top 50, Top 100 and Top 200, etc, but didn't follow any specification for the end. Top 250 in Year 250 was a happy coincidence.
Work out a scheme and I'll help scratch together a function to probe the length. It would look something like:
pyramidSize(seasons):
lookup = { /* some dict that sets the milestones. Has a tuple that indicates how much to increment after that point, and what the base number of players is */}
let M be the last milestone element that is smaller than seasons
if seasons < 50:
by convention, M->increment is defined to be 0 for these low seasons
return M->players
else:
let D be the number of decades to increment, being (seasons - N) / 10 with int division
return M->players + M->increment * D
@dumbmatter 👌 I'll take a look at the license agreement and take a crack at integrating it into the existing HoF page. Thanks for the feedback,
My wife and I had our baby on friday, so it'll be a bit of time before I take another look at this. But I plan to!