Skip to content

Latest commit

Β 

History

31 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MLBC Prospect Ranker

A browser-based prospect ranking engine for the Minor League Baseball Club (MLBC) simulation game. Upload your league export files and get instant, data-driven prospect rankings β€” no server, no Python, no installs required.

πŸ”— Live app: https://ddecoen.github.io/mlbc_prospect_ranking


Visual Design

Each prospect row displays three stacked grade bars, styled to match the sim's own player card layout:

Hitters

Bar Color What it measures
FLD Purple Fielding score β€” position-weighted range, arm, speed, hands
HIT Green Offensive score β€” OBP, XBH, K/BB, GB%, Pull
OVR Gold Overall (90% HIT + 10% FLD + all bonuses)

Pitchers

Bar Color What it measures
END Red Raw endurance value (shown as the actual END number, not a grade)
STF Blue Stuff score β€” pure W_OPS on the 20-80 scale
OVR Gold Overall (STUFF + END gate + all bonuses/penalties)

All bars fill proportionally on the 20–80 grade scale β€” a grade of 70 fills ~83% of the bar, grade of 50 fills ~50%, grade of 30 fills ~17%. This makes it easy to scan down the OVR column and compare prospects at a glance without reading individual numbers.

The GRADES column shows the underlying component grades (OBP, XBH, K/BB for hitters; WOPS, KBB for pitchers). The BONUSES column shows pills for all active adjustments β€” positional premiums, power/leadoff bonuses, SP/RP status, elite closer/BP/K/BB bonuses, walk penalties, and hit tool penalties.

  1. Export two CSV files from your MLBC sim:
    • League_Roster_XXXX.csv β€” full league player roster with all edits/grades
    • Pro_Years_Report_XXXX.csv β€” pro years report (filters to prospects with 0 pro years)
  2. Open the app and upload both files
  3. Rankings generate instantly in your browser β€” filter, sort, and export to CSV

Model Philosophy

The model is built around one core principle: grades are grades. A player's edits represent their true ability ceiling regardless of what level they play at. Level only tells you when you'll get the value, not how much value there is. No level-based adjustments are applied to scores.

The model separates hitters and pitchers completely, scoring each against the full non-ML prospect pool.


Hitter Model

HIT Score (90% of overall)

The offensive grade is built from five components on a 20–75 scale, calibrated to the full non-ML prospect population:

Component Weight Stat Logic
OBP Grade 40% (OBP_vL Γ— 0.25) + (OBP_vR Γ— 0.75) On-base is the most predictive offensive rate stat
XBH Grade 38% HRΓ—4 + 3BΓ—3 + 2BΓ—2 Extra base value mirrors the sim's own fantasy formula
K/BB Grade 15% B_SO / B_BB Plate discipline β€” lower is better
GB% Grade 4% B_GB Small power-style signal β€” low GB% = fly ball tendency
Pull Grade 3% Pull% Small pull-power signal

Why GB% and Pull are small weights: Early versions of the model weighted these at 12% and 8% respectively. This incorrectly penalized legitimate contact/gap hitters β€” a player who hits .845 OPS to all fields with a high GB% would score lower than a .803 OPS pull hitter. GB% and Pull are style signals, not outcome signals. OBP and XBH already capture the outcomes; GB% and Pull just add a small bonus for pull-power profiles without punishing other approaches.

Hit Tool Floor β€” Contact Credibility:

A poor hit tool creates two separate problems, both now modeled explicitly:

1. Contact-credibility discount on OBP grade. A player with B_H=155 cannot sustain a .390 OBP regardless of what his edit splits say β€” the splits assume a level of contact he can't produce. The OBP grade is discounted proportionally:

OBP_G = OBP_G_raw Γ— min(1.0, B_H / 170)

So B_H=155 β†’ OBP grade multiplied by 0.912 (9% discount). B_H=140 β†’ 18% discount. B_H=170+ β†’ no discount.

2. Flat hit tool penalty applied to the final overall score:

B_H Penalty Notes
β‰₯ 170 0 No penalty β€” acceptable contact
β‰₯ 160 βˆ’1 Slightly below average
β‰₯ 150 βˆ’3 Genuine contact risk
β‰₯ 140 βˆ’5 Significant red flag
< 140 βˆ’8 Cannot profile as a hitter

The old model used a single -1 penalty for B_H=155, which was far too lenient. A walk-heavy, no-contact player (the "Barry Bonds eye with no contact ability" profile) would score artificially high because the OBP grade trusted edit splits that the hit tool makes impossible to sustain in the sim.

FLD Score (10% of overall)

Defense is real but worth approximately 10% of a prospect's value. The sim's fantasy scoring is entirely offensive, but good defense helps pitchers and prevents runs.

Each position uses position-appropriate defensive weights with range z-scored within position group (so a 1B's range is compared to other 1Bs, not shortstops):

Position Primary Weight Secondary
C Arm 65% Hands 25%
SS Range 40% Arm 25%, Run 20%
2B Range 40% Arm 25%
3B Arm 45% Range 30%
CF Range 40% Run 35%
RF Arm 45% Range 30%
LF Range 40% Run 30%
1B Hands 55% Range 25%

Throw hand constraint: Left-handed throwers cannot play meaningful infield positions other than 1B. LH throwers coded at 2B/3B/SS use OF range as their range component, which correctly penalizes the positional mismatch.

Bonuses (additive to overall)

These bonuses recognize archetypes the sim rewards but raw grades don't fully capture:

Bonus Trigger Points Rationale
Positional Value C, SS, CF, 2B, 3B, RF, LF, 1B +3.0 to βˆ’0.5 Scarce defensive positions are worth more at equivalent offensive output
True Power OPS β‰₯ 1.050 +3.0 Generational bat β€” top 0.3% of prospect pool
OPS β‰₯ 1.000 +1.5 Elite power prospect
OPS β‰₯ 0.950 +0.5 Plus power
True Leadoff OBP β‰₯ 0.390 + Run β‰₯ 5.5 +2.0 Both OBP and speed elite simultaneously
OBP β‰₯ 0.380 + Run β‰₯ 5.0 +1.0 Legitimate leadoff profile
Bat Hand Switch +1.0 Platoon advantage every at-bat
Left-handed +0.5 Slight platoon advantage vs. majority RHP

Positional value premiums:

Premium positions (CF, SS, C) have athleticism-conditional bonuses β€” the premium only applies if the player can actually man the position at an above-average level.

For C and SS, the bonus is additionally scaled by the positional training rating (F_C and F_SS in the roster file, on a 0–1 scale). A catcher at F_C=0.51 gets 51% of the bonus β€” rewarding owners who properly train players at premium positions and correctly reflecting that an untrained catcher is a liability regardless of his arm. CF uses speed as the gate since speed is fixed in the sim and cannot be trained.

Position Condition Raw Bonus Scaling
C Arm β‰₯ 8.0 +3.0 Γ— F_C (0–1) β€” elite arm, top 25% of catchers
C Arm β‰₯ 6.5 +2.0 Γ— F_C (0–1) β€” good arm, real value
C Arm β‰₯ 5.0 +1.0 Γ— F_C (0–1) β€” fringe, modest premium
C Arm < 5.0 0 β€” bat must carry it; defense is a liability
SS IF_Rng β‰₯ 5.0 +2.0 Γ— F_SS (0–1)
SS IF_Rng β‰₯ 4.0 +1.0 Γ— F_SS (0–1)
SS IF_Rng < 4.0 +0.5 Γ— F_SS (0–1)
CF Run β‰₯ 5.5 +1.5 No scaling (speed fixed)
CF Run β‰₯ 4.5 +0.75 No scaling (speed fixed)
CF Run < 4.5 0 β€”
2B / 3B β€” +0.5 No scaling
RF / LF β€” 0 β€”
1B β€” βˆ’0.5 β€”

Example: Frank Prater has Arm=8.74 (raw bonus = +3.0, elite tier) but F_C=0.51 β†’ actual bonus = 3.0 Γ— 0.51 = +1.5. Once trained to F_C=1.0, he earns the full +3.0 β€” the true unicorn tier. Kevin Diaz (Arm=4.42, fully trained at F_C=1.0) gets +0 β€” a weak-armed catcher adds no positional premium regardless of training.


Pitcher Model

STUFF Score

The pitcher model is built on one core insight: in a sim with fixed pitch probability distributions, W_OPS is a complete and sufficient quality metric.

The sim engine selects pitches randomly according to each pitcher's usage percentages (P1_Qual through P6_Qual). You cannot instruct your pitcher to throw his fastball more often β€” the probabilities are fixed. This means:

  • The best pitch is already weighted into W_OPS by how often the sim calls it
  • The worst pitch is already weighted into W_OPS by how often the sim calls it
  • Pitch count doesn't matter β€” a 3-pitch pitcher who dominates with all three is equal to a 5-pitch pitcher with the same W_OPS
  • Top-2 or bottom-1 metrics double-count what W_OPS already captures

Walks are already captured in per-pitch OBP against, which flows directly into W_OPS. K/BB only appears as a bonus for true outliers β€” it does not penalize anyone.

Component Weight Stat Logic
W_OPS 100% Usage-weighted OPS against across all pitches Complete pitch quality signal β€” captures best, worst, mix, and command simultaneously

Why K/BB is not in STUFF: Walks are already reflected in per-pitch OBP against β€” a pitcher who walks batters has a worse W_OPS as a direct result. Penalizing K/BB on top of W_OPS double-counts the same walks and systematically underrates pitchers who get outs without strikeouts: groundball artists, soft-tossers, and deception-based arms. In a sim where a strikeout and a groundout are both just outs, K/BB is not an independent quality signal on top of W_OPS. A pitcher like Charlie Blanco β€” three pitches all under .720 OPS, 65% GB rate β€” should not be ranked at 555th because his K:BB ratio is unflattering. His pitch outcomes are what matter.

How W_OPS is computed:

W_OPS uses the actual batter handedness distribution from the league, not a naive 50/50 split:

  • LHP faces 76.4% RHH (R batters + switch hitters batting right vs LHP)
  • RHP faces 64.7% RHH

For each pitch: OPS_weighted = OPS_vL Γ— handedness_weight_L + OPS_vR Γ— handedness_weight_R

Then: W_OPS = Ξ£(pitch_usage Γ— OPS_weighted) across all pitches

This gives the true expected OPS on any randomly selected pitch, accounting for the actual distribution of batter types the pitcher will face.

Why not GB%? Ground ball rate is already implicit in W_OPS β€” a ground ball specialist allows fewer hits and fewer home runs, which shows up directly in his pitch OPS splits. Adding GB% as a separate component double-counts the same information while unfairly disadvantaging strikeout pitchers who achieve the same W_OPS through a different approach.

Why not K rate separately? Strikeouts are the best possible outcome (no baserunner, no defense required), but their value is already reflected in the per-pitch OPS against. A pitcher who strikes out 200 batters per 600 has a lower OPS against than one who strikes out 80, all else equal.

W_OPS grade scale is percentile-anchored to the actual non-ML prospect pitcher pool β€” not arbitrary absolute thresholds. This means grade 65 genuinely means top 10%, grade 70 means top 5%, and so on. Early versions used fixed OPS thresholds (e.g. grade 60 = W_OPS < 0.675) which compressed the entire top 5-15% of pitchers into two adjacent grades, causing quality arms to appear "below average" on the scale. The current bins:

Grade W_OPS threshold Pool percentile
80 < 0.638 Top 1%
75 < 0.659 Top 3%
70 < 0.678 Top 5%
65 < 0.703 Top 10%
60 < 0.719 Top 15%
55 < 0.736 Top 25%
50 < 0.764 Top 40%
45 < 0.811 Top 60%
40 < 0.855 Top 75%
35 < 0.908 Top 90%
30 β‰₯ 0.908 Bottom 10%

Walk Penalty (context-aware):

Extreme walk rates hurt real roster value, but the penalty is discounted when total baserunners (H + BB) are still under control. A pitcher who walks 60 batters but only allows 120 hits (H+BB=180) is a very different problem from one who walks 60 and allows 175 hits (H+BB=235).

Base penalty by walk count:

P_BB Base Penalty
β‰₯ 55 βˆ’1.0
β‰₯ 60 βˆ’1.5
β‰₯ 65 βˆ’1.75
β‰₯ 70 βˆ’2.0
> 75 βˆ’3.0

Context multiplier applied to the base penalty:

H + BB total Multiplier Rationale
< 170 Γ— 0.25 Walks acceptable β€” strong hit suppression compensates
170–200 Γ— 0.50 Manageable β€” worth monitoring
> 200 Γ— 1.0 Full penalty β€” walks compounding a hit problem

Example: P_BB=60, P_H=120 β†’ H+BB=180 β†’ penalty = βˆ’1.5 Γ— 0.50 = βˆ’0.75. Same walk count with P_H=175 β†’ H+BB=235 β†’ full βˆ’1.5.

STUFF Multiplier (SP only):

A starter's STUFF grade is multiplied by 1.07 before any bonuses are applied (capped at 80). This reflects a fundamental sim reality: a starting pitcher affects more plate appearances per game than any position player. A hitter bats 4-5 times per game; a starter faces 27+ batters every 5 days. The 7% lift brings pitcher grades onto a comparable value scale with hitter grades before bonus stacking begins. Relievers do not receive the multiplier.

SP Quality Bonus:

Elite starters receive an additional bonus based on their scaled STUFF grade (post-multiplier):

Scaled STUFF Bonus Profile
β‰₯ 75 +3.0 True ace
β‰₯ 70 +2.0 Solid #2 starter
β‰₯ 65 +1.5 Quality starter
β‰₯ 60 +1.0 Good starter
< 60 0 No bonus

Relievers never receive the SP quality bonus regardless of grades.

Endurance Bonus:

A workhorse starter who can go deep into games has roster value beyond pitch quality alone. Requires a quality gate (scaled STUFF β‰₯ 55) so a pitcher with poor edits doesn’t benefit just from eating innings badly:

Condition Bonus
END β‰₯ 8.0 + STUFF β‰₯ 55 +2.0
END β‰₯ 7.5 + STUFF β‰₯ 55 +1.0

GB% Bonus (SP only):

Groundball pitchers are systematically undervalued by W_OPS alone. W_OPS captures OBP and SLG against but not the type of contact β€” a pitcher allowing 65% grounders prevents the extra-base hits and home runs that a fly-ball pitcher with the same W_OPS would give up. Requires a quality gate (STUFF β‰₯ 55) so a poor pitcher doesn't benefit just from weak contact:

Condition Bonus
GB% > 60% + STUFF β‰₯ 55 +1.5
GB% > 55% + STUFF β‰₯ 55 +1.0

Only ~10-15 SP prospects qualify at the top tier, keeping it a meaningful differentiator rather than a broad inflation. Directly addresses the concern from experienced owners that control/groundball arms were being undervalued relative to strikeout pitchers with similar W_OPS.

Why these adjustments exist: Analysis showed pitchers represented only 14% of the top 50 despite being 43% of the prospect pool. Hitters stack up to +10 points in bonuses (positional premium + power + leadoff + bat hand) while pitchers had no equivalent. The 1.07 multiplier + bonuses bring pitchers to ~28% of the top 50 and ~35% of the top 100. The multiplier of 1.07 was chosen specifically to avoid overcorrection β€” higher values pushed average pitchers ahead of genuinely elite hitters.

  • END β‰₯ 5.0 β†’ Starter-eligible, no adjustment
  • END < 5.0 β†’ Reliever penalty (βˆ’3 points)

The penalty was reduced from βˆ’5 to βˆ’3 because some high-quality relievers have genuine roster value as swingmen or high-leverage arms. A βˆ’5 gate was washing out pitchers who belong in the top 200 regardless of role.

Elite Closer Bonus (+2.0):

A reliever with true ace-level pitch quality AND elite command is a genuine asset regardless of endurance. If a pitcher meets all three conditions:

  • END < 5.0 (reliever role)
  • W_OPS < 0.660 (top ~2.5% of the prospect pitcher pool)
  • K/BB > 3.0 (elite command)

…he receives a +2.0 bonus. This partially offsets the βˆ’3 reliever penalty, netting βˆ’1 overall β€” correctly placing an elite closer just slightly below an equivalent starter.

Elite BP Arm Bonus (+2.0):

A swingman/setup arm in the END 4.0–4.9 tier with quality stuff and decent command also receives a +2.0 bonus:

  • END 4.0–4.9 (swingman tier β€” not a true closer, not a starter)
  • W_OPS ≀ 0.680 (top ~5% of the prospect pitcher pool)
  • K/BB > 2.5 (sufficient command)

Elite K/BB Bonus (+2.0):

Any pitcher β€” starter or reliever β€” with K/BB > 4.0 receives a +2.0 bonus. This is the top ~3% of the prospect pool and represents truly elite command that is meaningful on top of W_OPS (since K/BB is not otherwise penalized in STUFF).


Grade Scale

All grades use the standard scouting 20–80 scale:

Grade Meaning Pool percentile (approx)
80 Elite β€” top 1% of prospect pool 99th+
75 Plus-plus β€” top 2–3% 97th–99th
70 Plus β€” top 5% 95th–97th
65 Above average 85th–95th
60 Solid average+ 75th–85th
55 Average 60th–75th
50 Below average 40th–60th
45 Fringe 25th–40th
40 Poor 10th–25th
35 Well below average 3rd–10th
20–30 Bottom of pool Bottom 3%

Why the full 80 is available: In traditional prospect evaluation, grades are capped at 75 for prospects to leave headroom for development β€” a player rated 75 today might grow into an 80. In a sim, edits are fixed. A player with a .420 OBP edit will always have a .420 OBP edit. There is no development ceiling to protect, so a player whose grades genuinely put him in the top 1% of the prospect pool receives the 80 he deserves.

Bins are calibrated to the full non-ML prospect population so grades are consistent year over year regardless of which season's data is uploaded.


Why These Decisions

No level adjustment: The MLBC edits represent a player's true ability grades β€” they do not change as a player moves from A-ball to AAA. A 19-year-old in A-ball with elite grades should not be ranked below a 24-year-old in AAA with average grades just because he hasn't been promoted yet. Level tells you when you get the value. The ranking tells you how much value there is.

90/10 bat/glove for hitters: Analysis of the sim's fantasy scoring formula (1B=1, 2B=2, 3B=3, HR=4, BB=1, SO=βˆ’1) shows that offensive production drives virtually all measurable value. The run value difference between elite and poor defense is approximately 3–4 runs per season, while a single extra OPS point represents ~0.4 runs per 600 AB. The bat-to-glove run value ratio is approximately 10:1.

GB% and Pull as small signals, not large weights: GB% and Pull were originally weighted at 12% and 8% of HIT respectively. This created a systematic bias against contact/gap hitters β€” a player hitting .845 OPS to all fields would score lower than a .803 pull hitter because his high GB% and low Pull% dragged down his HIT score. GB% and Pull are style signals, not outcome signals. OBP and XBH already capture the outcomes. Reducing these to 4% and 3% means they add a small bonus for pull-power profiles without penalizing other legitimate hitting approaches.

Conditional positional premiums: The positional bonus should only apply when the player can actually play the position at a premium level. A CF with below-average speed (Run < 4.5) is really a corner outfielder playing center β€” giving him the same +1.5 bonus as a true center fielder with elite speed would systematically overrate him. The same logic applies to SS (gated on range) and C (gated on arm strength). Fixed bonuses based purely on the roster position label, regardless of whether the player has the tools to play it, produce rankings that no experienced scout would recognize.

Positional premiums instead of defensive scoring inflation: Rather than letting fielding grades inflate overall scores for corner players (a known bug in earlier versions of this model), positional scarcity is handled as a clean additive bonus. This correctly ranks a .850 OPS shortstop above a .850 OPS first baseman without letting IF_Rng artificially boost a first baseman's score.

W_OPS as the complete pitcher signal: Early versions of the model added components like Top-2 pitch quality, worst pitch OPS, and strikeout rate on top of W_OPS. All of these are wrong for the same reason: the sim selects pitches from a fixed probability distribution. You cannot instruct your pitcher to throw his fastball more. Because the usage percentages are fixed sim probabilities, W_OPS already captures every aspect of pitch quality β€” the best pitch is weighted by how often the sim calls it, the worst pitch is weighted by how often the sim calls it, and everything in between. Adding any pitch-specific component on top of W_OPS is double-counting. K/BB is only rewarded as a bonus for true outliers (K/BB > 4.0), never penalized.

Percentile-anchored W_OPS bins: Early bin calibration used arbitrary absolute OPS thresholds that compressed the entire top 5–15% of pitchers into two adjacent grade buckets. A pitcher in the top 5% of the pool was getting a grade of 55 β€” "below average" on the 20-80 scale. The current bins anchor each grade to an actual percentile of the non-ML prospect pitcher pool so that grade 65 genuinely means top 10%, grade 70 means top 5%, and so on. This fixed systematic underrating of quality pen arms whose W_OPS fell just outside the elite tier.

No GB% for pitchers: Ground ball rate is already embedded in W_OPS β€” a pitcher who generates grounders allows fewer hits and fewer home runs, which shows directly in his pitch OPS against. Adding GB% as a separate term double-counts it while penalizing strikeout pitchers who achieve the same W_OPS through a different approach. Both are valid pitcher archetypes; W_OPS correctly treats them equivalently at the same run prevention level.


Roster Column Reference

The app expects the standard MLBC CSV export format. Key columns used:

Hitters: Bat, Throw, Run, Arm, IF_Rng, OF_Rng, Fld, B_H, B_B2, B_B3, B_HR, B_BB, B_SO, vL_OBP, vL_SLG, vR_OBP, vR_SLG, Pull, B_GB

Pitchers: Throw, END, P_SO, P_BB, P1–P6, P1_Qual–P6_Qual, P1_vL_OBP–P6_vR_SLG

Both: Last, First, Age, Pos, Team, Level

Pro Years Report: Firstname (or First), Lastname (or Last), Pro Years


License

MIT License β€” see LICENSE for details. Free to use, modify, and share.


Contributing

Pull requests welcome. Key areas for improvement:

  • Catcher framing bonus (arm data exists but framing grade does not)
  • Multi-position eligibility display
  • Career trajectory tracking across seasons
  • Draft board mode (A-ball only filter with pick slot context)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages