Skip to content

Options to configure min/max age of draft prospects and force retire players at certain age #354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 49 commits into from
Mar 28, 2021

Conversation

domini7
Copy link
Contributor

@domini7 domini7 commented Feb 7, 2021

image
image

Draft ages can really mess up the talent of a league if they aren't close to the default. Prospects below the default min age (19) seems to be just as good as default, which absolutely balloons the talent. IMO would be better if somehow they would be generated with worse ratings. - touched up in 499c58b

Something I want to do about force retire but not sure how, when importing a league file with it set to a number (lets say 32), I want to make sure the league does NOT generate players older than 32. Right now it does which is awkward.

Just like any other extreme god mode option (death rate, gamesim settings), people can make their leagues wonky, but nothing wrong with that.

Other than all that, fun, cool, highly requested feature! Allows to copy some international leagues that allow 16 year olds, or the WNBA which only allows seniors.

@dumbmatter
Copy link
Member

Ages of draft prospects is a good idea, if you can make the ratings behave reasonably (like I see you talking about on Discord).

Force retire age... what's the use case? To simulate college sports? If that's it, then there are so many other differences with college sports, I'm not sure it's worth adding. It would still be unsatisfying.

@domini7
Copy link
Contributor Author

domini7 commented Feb 7, 2021

Force retire age... what's the use case?

I've been playing with a league with it set to 25 where there's constantly new generations of players. It's really interesting honestly, the dynamic of having to play around the fact that my star player won't be around for much longer, drafting the youngest players are key. Fun things to do with it. Simulating a college league is partly possible which is neat, but it can go deeper. Simulate a freakin middle school league. U11 leagues. Possibilities are endless with what people can do with that option

@domini7
Copy link
Contributor Author

domini7 commented Feb 7, 2021

If that's it, then there are so many other differences with college sports

This can be said with any other leagues that aren't NBA, like Europe leagues, FIBA. Yet, people still create those leagues for BBGM with teams and league structure despite not being able to fully recreate what those leagues offer.

@domini7
Copy link
Contributor Author

domini7 commented Feb 7, 2021

U11 rec league with 8 draft rounds and prospects aged 9-10 is actually pretty fun

@dumbmatter
Copy link
Member

Okay, that convinces me enough.

About players in new leagues, the way it works is it simulates 20 past drafts to generate all the players https://github.com/dumbmatter/gm-games/blob/d3554459319bf558c44ff3bf092df30da06dc740/src/worker/core/league/create.ts#L471

In your use case, I guess you wouldn't need 20 past drafts. But you'd need more rounds per draft to compensate... might need better error handling in that case, to automatically increase that value, or people will find it annoying.

@domini7 domini7 changed the base branch from hockey to master February 8, 2021 10:43
@domini7
Copy link
Contributor Author

domini7 commented Feb 8, 2021

That last commit needs some work to make it less repetitive. I tried to declare an array of ratings then looping to subtract but I get an error.

const rtgs = ["spd", "jmp]
for (rtg of rtgs) {
    ratings[rtg] -= subAmount;
}

When running lint, I get
Element e 'any' can't be used to index type '{ stre: number; spd: number; jmp: number; g: number; tp: number; oiq: number; diq: number; drb: number; pss: number; reb string; pot: number; season: number; skills: never[]; }'.
I tried googling but I can't figure it out!

@domini7
Copy link
Contributor Author

domini7 commented Feb 8, 2021

ageDraft command is complete and works pretty well with scaling

@dumbmatter
Copy link
Member

That last commit needs some work to make it less repetitive. I tried to declare an array of ratings then looping to subtract but I get an error.

const rtgs = ["spd", "jmp]
for (rtg of rtgs) {
    ratings[rtg] -= subAmount;
}

When running lint, I get
Element e 'any' can't be used to index type '{ stre: number; spd: number; jmp: number; g: number; tp: number; oiq: number; diq: number; drb: number; pss: number; reb string; pot: number; season: number; skills: never[]; }'.
I tried googling but I can't figure it out!

When you write something like const rtgs = ["spd", "jmp"];, TypeScript interprets it as "array of strings". So then in ratings[rtg], all it knows is that rtg is a string, and yet it also knows that ratings only accepts a limited subset of strings as keys. That's what the error is about.

Easiest fix is to change it the array declaration to const rtgs = ["spd", "jmp"] as const;, which tells TypeScript "this isn't any old array of strings, it is a specific array containing only the elements spd and jmp". Then when you call ratings[rtg] it knows that is safe.

@dumbmatter
Copy link
Member

Also can you give me write access to this branch (or your whole repo)? I haven't actually done anything, but I want to look at this soon, and might be easier if I can push a commit to the PR branch.

// If the youngest players generated aren't 19, scale ratings to match age
const age = g.get("draftAge")[0];
if (age !== 19) {
// Youngest prospects != 19 will be scaled, scaling stops at age 14 and 28
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you take another look at all these?

  • Basketball is currently scaled from 12 to 28, not 14 to 28
  • Football is currently scaled from 14 to 30, not 14 to 28
  • Hockey is currently scaled just like basketball, but I'm not sure if that's intended because in the other two sports you use the same age in the scale formula as in the if right before it. If it's intended for those two numbers to always be the same, use a constant like const DEFAULT_MIN_AGE = 19; (different in each file). That prevents them from ever getting out of sync.

If the goal was to have all the age ranges the same for every sport, like the comments suggest, I recommend you put the helpers.bound around age, not around the entire scale formula. Then it'll be much more clear what's going on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good eye, give me a minute

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so some reasoning behind these numbers if you aren't sure. I set the min max age scaling limits to prevent super leagues (So not every prospect is a 90 OVR demigod for 35 year old DP's) and to prevent trash prospects with a rating of 0 in every single rating. So hitting the max scaling will produce a class that looks like a typical league (few studs, lot of role players), and the min scaling will at least give some promising players instead of everyone being absolute trash.

@@ -198,6 +198,37 @@ const genRatings = (
pots: { ...defaultOvrsOrPots },
};

// Youngest prospects !== 18 will be scaled, scaling stops at age 13 and 26
let age = g.get("draftAges")[0];
age = helpers.bound(age, 13, 26);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why different than other sports?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I left it the same as BBGM/FBGM, there were an absurd absurd number of superstars. Players below the min scaling were also a bit too good.

"diq",
] as const;
// These ratings develop slowly compared to others, so they scale less. Works well in testing
const rtgsDevelopSlow = ["spd", "jmp", "drb", "pss", "reb"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't fix it, I'm doing it, but... these are never getting applied!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bruh

@@ -357,6 +357,43 @@ const genRatings = (
pots: { ...defaultOvrsOrPots },
};

// Youngest prospects !== 21 will be scaled, scaling stops at age 14 and 30
let age = g.get("draftAges")[0];
age = helpers.bound(age, 14, 30);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why you want an upper bound (because at some age, players stop development, so continuing to boost them after that would make super players).

But why do you want a lower bound? No matter how low a player's age, he's still going to be improving every year.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is subjective, but ages under 10 have a lot of 0 ovr players, so it's not rly fun if you want to do some little kid league and have to deal with most of the players being incompetent (maybe realistic). Bigger thing, if everyone becomes 0 OVR, everyone will end up developing in very similar styles and only be separated by height rating.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could lower it or remove it if you believe its better, i just didn't really like it without a min limit

@dumbmatter
Copy link
Member

Did a little refactoring (moving the age adjustment code to one place for all sports), lmk if it looks okay.

Also made the lower bound of the adjustment unbounded, but still small enough at 0 that you get some diversity of players.

Also did this fun thing, for displaying the 1st quartile, median, and 3rd quartile ovr ratings at different draftAges values:

$ SPORT=basketball yarn jest src/worker/core/player/genRatings.test.ts | grep QUARTILES
PASS src/worker/core/player/genRatings.test.ts (51.776 s)
  worker/core/player/genRatings
    ✓ no error with restricted draftAges and forceRetireAge settings (50079 ms)

    QUARTILES at default [ 31, 57, 74 ]
    QUARTILES at age  0  [ 29, 57, 76 ]
    QUARTILES at age  5  [ 29, 57, 77 ]
    QUARTILES at age 10  [ 34, 60, 75 ]
    QUARTILES at age 15  [ 36, 55, 63 ]
    QUARTILES at age 20  [ 40, 47, 55 ]
    QUARTILES at age 25  [ 31, 36, 43 ]
    QUARTILES at age 30  [ 27, 34, 45 ]
    QUARTILES at age 35  [ 20, 28, 37 ]
    QUARTILES at age 40  [ 17, 22, 34 ]
    QUARTILES at age 45  [ 16, 22, 33 ]
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        52.144 s
Ran all test suites matching /src\/worker\/core\/player\/genRatings.test.ts/i.
$ SPORT=football yarn jest src/worker/core/player/genRatings.test.ts | grep QUARTILES
PASS src/worker/core/player/genRatings.test.ts (29.417 s)
  worker/core/player/genRatings
    ✓ no error with restricted draftAges and forceRetireAge settings (27772 ms)

    QUARTILES at default [ 38, 46, 55 ]
    QUARTILES at age  0  [ 51, 62, 75 ]
    QUARTILES at age  5  [ 56, 67, 78 ]
    QUARTILES at age 10  [ 59, 69, 78 ]
    QUARTILES at age 15  [ 54, 61, 69 ]
    QUARTILES at age 20  [ 41, 49, 57 ]
    QUARTILES at age 25  [ 25, 30, 37 ]
    QUARTILES at age 30  [ 21, 27, 34 ]
    QUARTILES at age 35  [ 17, 20, 27 ]
    QUARTILES at age 40  [ 17, 20, 26 ]
    QUARTILES at age 45  [ 16, 20, 26 ]
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        29.793 s, estimated 52 s
Ran all test suites matching /src\/worker\/core\/player\/genRatings.test.ts/i.
$ SPORT=hockey yarn jest src/worker/core/player/genRatings.test.ts | grep QUARTILES
PASS src/worker/core/player/genRatings.test.ts (8.531 s)
  worker/core/player/genRatings
    ✓ no error with restricted draftAges and forceRetireAge settings (6876 ms)

    QUARTILES at default [ 43, 50, 57 ]
    QUARTILES at age  0  [ 26, 43, 61 ]
    QUARTILES at age  5  [ 32, 48, 64 ]
    QUARTILES at age 10  [ 37, 50, 64 ]
    QUARTILES at age 15  [ 40, 50, 59 ]
    QUARTILES at age 20  [ 45, 49, 56 ]
    QUARTILES at age 25  [ 40, 46, 51 ]
    QUARTILES at age 30  [ 35, 42, 50 ]
    QUARTILES at age 35  [ 28, 37, 45 ]
    QUARTILES at age 40  [ 24, 31, 42 ]
    QUARTILES at age 45  [ 23, 28, 40 ]
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        8.899 s, estimated 30 s
Ran all test suites matching /src\/worker\/core\/player\/genRatings.test.ts/i.

Maybe football needs a more severe penalty for young players...

@domini7
Copy link
Contributor Author

domini7 commented Mar 27, 2021

looks good 👍

@domini7
Copy link
Contributor Author

domini7 commented Mar 27, 2021

I'm assuming you didn't mean to leave default at [0, 0], but if you did then myb

@dumbmatter
Copy link
Member

I made one more commit f1b5530 which tweaks the aging parameter for FBGM and also improves the age distribution in new leagues.

It's definitely not perfect, some settings do weird things, the parameters could still be tuned better. But I think it's good enough to release now. I'll just wait for you to give the final approval, boss!

@domini7
Copy link
Contributor Author

domini7 commented Mar 28, 2021

**Release**

@dumbmatter dumbmatter merged commit d714359 into zengm-games:master Mar 28, 2021
@domini7 domini7 deleted the age-gen branch April 1, 2021 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants