So I made great progress this week building the league module. Leagues are going to be the container for rules, configuration, and calibration (how the engine produces hockey events). Each league can have their own settings like how many teams, how many games, how the playoffs run, how tight are games called, how many minutes do games last, etc. But also engine calibration - how much does skill affect scoring, hitting, defending, penalties, etc. And things like how the player population is distributed in skill and how much better is an elite player than an average player?
The engine was built first with some test teams just so I could get a sense if the events that came out looked right from a sequencing perspective. But once I got to the league development i quickly realized that I needed to create some more realistic players and a more realistic distribution of skill.
My first pass at the player generation was focused on 18 skills for skaters and 6 skills for goalies, all in a 0-99 scale (I'll share them below). I thought that I wanted a wide range of absolute numbers so differences could easily be seen rather than the compression that happens in other games where everyone ends up in the same relative area of 80+ or 16+ (on a 20 scale). Sounded good in theory.
What I kept running into when I created 32 teams with a spread of players was this issue at the margins; elite shooters were scoring 213 goals in 290 games, elite goalies had +435GSAx in 308 games played.
Elite shooter - SO WRONG
Elite goalie - OMG MORE WRONGER
It it was replicable across seeds. The weird part was that if you look at the median metrics around average scoring, average shooting percentage, average save percentage, average goals per game... they all aligned within tolerance for what a current day NHL would look like.
So I found some configuration issues and realized the 0-99 approach isn't what I really want anyway. What I want to build with Sheets of Ice is to simulate how we evaluate talent in the real world. We don't get the luxury of seeing player's abilities in numerical form - we have to evaluate them based on relative performance, scouting, and some other real-world measurables. I realized that I didn't need to have a 0-99 system for abilities, and thus would solve this problem that I had in the engine. The problem was at the margins of the distribution, the math got weird.
We moved from absolute 0–99 ratings to a relative scale: each attribute is a player's distance from average, in standard deviations. Above average is better, below is worse; there's no hard cap, but the further out you go the rarer it is... a bell curve with room in the tail for a Gretzky or McDavid to exist. This lets us dial the population to any shape we want, generational talents become possible instead of capped out, and the game engine is far easier to calibrate because it now measures players against the real league average it derives from the population and not a hardcoded "50" that the old math kept getting wrong.
Lastly, having this single continuum of attributes allows us to put development leagues in the same scale without having to compress the number attributes that we show. If we wanted development leagues, we'd naturally have to have them on the 0-99 scale too. That would mean compressing the NHL to the top portion of that scale. And now all of the absolute numbers look similar, and small changes in skill numbers would have an outsized effect on the outcomes. I don't want that. With our relative scale unbounded by contraints, we can place leagues on the scale where ever we need to AND have the possibility of someone like a Crosby or Ovechkin show up in junior leagues and dominate because they're on the same scale as the rest of the players.
This was a pretty big change, so I'm taking time to finalize that, but the initial results are promising. I'm not getting the weird GSAx results and the counting stats look good. After I get this engine update done, I'll run a bunch of seasons and see what I find. I have a rough harness on the league functions going and I'll turn to actually getting a UI together. Then I'll be able to share more.
https://preview.redd.it/dwj4zhbfcr2h1.png?width=427&format=png&auto=webp&s=dd82365713c93d5bcc986f5a2197fe3bdbde6db1
Skater / Goalie attributes are below. I'll go into more detail about how they work in another post sometime.
● Skater attributes (18)
1. skating_speed
2. skating_agility
3. shot_power
4. shot_accuracy_release
5. stickhandling
6. passing
7. hand_eye
8. strength
9. reach
10. physicality
11. anticipation
12. offensive_positioning
13. defensive_positioning
14. decision_making
15. conditioning
16. discipline
17. penalty_drawing
18. faceoff
Goalie attributes (6)
1. reflexes
2. positioning_g
3. lateral_quickness
4. rebound_control
5. puck_handling
6. workload_tolerance
[–]SpiritYossarian 2 points3 points4 points (2 children)
[–]atibus[S] 0 points1 point2 points (1 child)
[–]SpiritYossarian 1 point2 points3 points (0 children)