Jump to content

Kccitystar

Administrator
  • Posts

    8131
  • Joined

  • Days Won

    42

Contact Methods

  • Website URL
    http://www.mvpmods.com
  • Facebook
    https://www.facebook.com/mvpmods/
  • Twitter
    https://twitter.com/firstbaseman

Profile Information

  • Location
    New York, NY
  • Interests
    Baseball, Video Games, Books and Music

Recent Profile Visitors

57581 profile views

Kccitystar's Achievements

Legend

Legend (10/10)

  1. Yep, autosave is in. MVPEdit Pro will edit a .mvpdb project file the entire time (it's an sqlite database), so I’m planning an auto-recovery system similar to Microsoft Office where the editor periodically creates a recovery snapshot in case of a crash every 10 minutes. It won’t automatically export or overwrite roster DAT files, so manual saves and exports are still going to be explicit actions. Just one of those "feels right" kind of things.
  2. There will be an extensive guide to how the roster editor works and how ratings work in MVP when the tool is released, I can assure you
  3. A 4, 9, or 12 in HR vs L/R is not a direct percentage and does not map 1:1 to the hit chart. They're basically 0-15 values that are just tuning "buckets" for tendencies. Weights basically vs outcome shares. EA does this for a lot of fields (as I mentioned previously) to put guys into clear tiers and keep AI behavior stable from game to game, and it avoids tiny changes swinging results dramatically. So it's not so much “this many percent of hits will be home runs" but more like "how strongly a hitter is nudged toward home-run outcomes when a home run is already possible”. People like to assume there *should* be a formula but there isn't. So when you see HR = 9 (0–15 scale) and Power = 80 (0–99 scale), your brain wants to try and translate what that 9 means on the 99 scale, but MVP never asks that question internally. Instead, it asks: What kind of hitter is this? (0–15) Within that kind, how often do good outcomes happen? (0–99) And those answers never really collapse into a single number. When you see HR vs L = 4, or HR vs R = 9, or power hitters with 12, think of it like a nudge, not a percentage. Actually, you can think of it like lottery tickets in a hat: A hitter with HR = 4 has some tickets for home runs A hitter with HR = 9 has more tickets A hitter with HR = 12 has a lot of tickets But if the situation doesn’t allow a home run (bad pitch, weak contact, wrong zone, etc.), those tickets never get used. The game doesn’t force a home run just because the number is high. The hit chart percentages (GB / FB / LD / HR) are outcomes over time, after everything is factored in (contact quality, pitch type, location, count, handedness, etc.). The HR rating influences that process, but it doesn’t define it. So two hitters might both show a 5 HR in the chart, but one gets there through raw power, and the other gets there through mistake pitches and favorable counts. Same result, different paths. MVP designed ratings this way so it keeps games believable, it avoids one bad pitch deciding everything, and it makes elite power show up naturally over time while not making things feel scripted. It's less flashy but more baseball-like, if this all makes sense. Hope this helps!
  4. So an update: Doing Things the Boring (Correct) Way I’ve been working on the less flashy but very important side of the editor: making sure roster imports are safe, predictable, and transparent. MVPEdit Pro now has a proper DAT import pipeline that takes the original MVP Baseball 2005 roster files and converts them into a modern database format without silently changing things behind the scenes. The goal here is trust first, right? If the editor fixes something, it should tell you. So, one big example: the tool now detects and automatically corrects a known legacy issue in older rosters involving a missing attribute in lhattrib.dat, dating back to MVP 2004. Basically, there was no column for hitter tendencies when chasing late-breaking pitches (like sliders and slurves) against left-handed pitchers. The game has the pitch movement, but no hitter-side behavior to react to it, so everyone responded the same way with a 0 rating. This will be fixed when you import a roster by adding the column in and shifting every other column to the right. This will sadly break importing to MVPEdit since it will not recognize that change (the data shape is now different from what it expects), but to me that’s an acceptable tradeoff. The goal here is to move forward with a correct data model, not keep papering over legacy limitations. The fix will restores the missing attribute, but it won’t invent ratings...yet, but that’s intentional though. Assigning values is an editing decision, not a repair step :) When you import DAT files, the editor: detects the legacy format, applies the fix safely, explains exactly what changed, and continues the import. No mystery behavior, no broken rosters. I also added some quality-of-life polish: clear import success messages, readable warnings instead of cryptic errors, and status bar feedback so you always know what state the roster is in. Next up is dirty-state tracking (showing when a roster has unsaved changes), which opens the door to real editing and eventually undo/rollback support. The way I visualized it in my notes, basically the status bar (where in the image I linked says "Import completed with 1 warning(s)") will say something like "Pending Changes: (your most recent edit) + X others (if applicable)". The name of the roster on the titlebar will also have an asterisk to give you visual cues to save your roster. Classic MVPEdit did not have a way of telling you this, so a lot of the time if you fat-fingered a value or a name and then moved on to work on something else within the MBE, that was pretty much it. First draft, final draft. I'm all about modernizing the workflow with MVPEdit Pro. I'm going to probably add a "View Edit History" feature that will show your last 10 changes in a small window. This is what I got in my designer in Visual Studio (I'm coding in C#): Something that can inform you, like: Time | Player ID | Action ----------------------------------------------- 21:43:12 | 004512 | Changed Contact vs LHP 21:41:05 | 000983 | Updated Slider Control 21:39:22 | (Bulk) | Bulk Edit: Plate Discipline And maybe you can double click on one of these to revert the change (which would then move everything after it into a "redo" state until you make an unrelated change not in the history, which will sensibly clear the "redos" out) I haven't started with actually making use of the data yet to show anything but that's easy stuff. It's still the early days, but the foundation is taking a really good shape and it'll be future-proof. Still more features to go.
  5. I will work on a config profile for you, what kind of TKL keyboard is it? If it's like 75% or 60% it'll be a challenge but a full TKL keyboard is doable
  6. A note on how pitch families and hitter tendencies fit together Now that we’ve spent time understanding what each of the major blocks does: <cpubatter>, <batterai>, <batter>, and <pitcher>, it helps to zoom out a little and talk about how all of this works together. Especially when you look at the tendencies the game shows you in-game when you modify playere tendencies: Fastball, Curveball, Slider, with things like Take, Chase, and Miss split by left- and right-handed pitchers. The first thing to understand is that MVP doesn’t really think in terms of pitch names the way we do. It’s not sitting there saying, “That was a slider,” or “Here comes a curveball.” Instead, the game groups pitches into a few broad families based on how they behave. Some pitches challenge you with speed, some mess with your timing, and some fool you with sharp movement. The Fastball, Curveball, and Slider labels you see in the game's Edit Player screen are really just friendly ways of describing those families. That’s where <cpubatter> comes into play. Like we said before, this block is basically the CPU hitter’s eyes and instincts. When a pitch is on the way, <cpubatter> is asking a very human question: Does this pitch look like something I should swing at? The Take, Chase, and Miss tendencies in the Edit Player menu live right here. “Take vs RHP” isn’t about patience in general but about how comfortable a hitter feels laying off that kind of pitch from a right-handed pitcher. “Chase vs LHP” is about how often the hitter gets tempted by something that looks good at first but really isn’t. It’s all about perception and confidence, not results. If the hitter does decide to swing, the game hands things off to <batterai>. It asks, Okay, given the pitch, the timing, and the hitter’s strengths, how good was that swing? Fastball-type pitches tend to punish late reactions, slower breaking pitches tend to throw off timing, and harder breaking pitches are the ones that make hitters look really uncomfortable. <batterai> takes all of that and quietly sorts the swing into a quality tier. It still isn’t deciding where the ball goes, it’s just setting the stage. Once that’s done, <batter> takes over and does the visible work. This block doesn’t care what kind of pitch was thrown. It only cares about the swing quality it was given. From there, it shapes the ball’s exit speed, launch angle, spin, and trajectory within safe, believable limits. That’s why MVP’s hits have so much variety but still feel grounded. The chaos has already been filtered out earlier. On the other side of the matchup is <pitcher>. This block isn’t trying to be clever or strategic. Its job is to quietly control how sharp and reliable pitches are allowed to be, especially as fatigue sets in. Over time, pitches lose a little bite, miss their spots a bit more often, and become easier to read. That gradual pressure is what gives hitters more chances later in games without anything feeling sudden or artificial. When you put it all together, those Fastball, Curveball, and Slider tendencies in the Edit Player screen start to make a lot more sense. They’re not separate systems or hidden tricks. They’re just different ways of describing how a hitter reacts to different kinds of deception, from different pitchers, in different situations. Nothing here guarantees success or failure. It all just gently nudges probability. That’s the real heart of MVP’s design. Pitch sequencing works not because the CPU is smart, but because the game understands that different pitches test different weaknesses. Ratings don’t decide a single swing but rather shape how things unfold over time.
  7. This is my controller.cfg settings for the 8BitDo SN30 Pro. There's two settings here, one in D-Input Mode and one in X-Input Mode: profile= Bluetooth_XINPUT_compatible_input_device device= Bluetooth_XINPUT_compatible_input_device player= 0 number_of_buttons= 16 number_of_povs= 1 number_of_axis= 5 VPAD_VIRTUAL_BUTTON_START= button 8 VPAD_VIRTUAL_BUTTON_SELECT= button 7 VPAD_VIRTUAL_BUTTON_CROSS= button 1 VPAD_VIRTUAL_BUTTON_CIRCLE= button 2 VPAD_VIRTUAL_BUTTON_SQUARE= button 3 VPAD_VIRTUAL_BUTTON_TRIANGLE= button 4 VPAD_VIRTUAL_BUTTON_L1= button 5 VPAD_VIRTUAL_BUTTON_R1= button 6 VPAD_VIRTUAL_BUTTON_L2= axis- 3 VPAD_VIRTUAL_BUTTON_R2= axis+ 3 VPAD_VIRTUAL_BUTTON_L3= button 9 VPAD_VIRTUAL_BUTTON_R3= button 10 VPAD_VIRTUAL_BUTTON_DPAD_UP= pov0 1 VPAD_VIRTUAL_BUTTON_DPAD_DOWN= pov180 1 VPAD_VIRTUAL_BUTTON_DPAD_LEFT= pov270 1 VPAD_VIRTUAL_BUTTON_DPAD_RIGHT= pov90 1 VPAD_VIRTUAL_BUTTON_L_STICK_RIGHT= axis- 1 VPAD_VIRTUAL_BUTTON_L_STICK_LEFT= axis+ 1 VPAD_VIRTUAL_BUTTON_L_STICK_UP= axis+ 2 VPAD_VIRTUAL_BUTTON_L_STICK_DOWN= axis- 2 VPAD_VIRTUAL_BUTTON_R_STICK_RIGHT= axis- 4 VPAD_VIRTUAL_BUTTON_R_STICK_LEFT= axis+ 4 VPAD_VIRTUAL_BUTTON_R_STICK_UP= axis+ 5 VPAD_VIRTUAL_BUTTON_R_STICK_DOWN= axis- 5 VPAD_PITCH_1= button 1 VPAD_PITCH_2= button 2 VPAD_PITCH_3= button 3 VPAD_PITCH_4= button 4 VPAD_PITCH_5= button 6 VPAD_FIELD_PICK_OFF_THROW_FIRST= button 2 VPAD_FIELD_PICK_OFF_THROW_SECOND= button 4 VPAD_FIELD_PICK_OFF_THROW_THIRD= button 3 VPAD_PITCH_OUT= button 1 VPAD_THROW_BALL= not_assigned -1 VPAD_INTENTIONAL_WALK= button 3 VPAD_INTENTIONAL_HITBATTER= button 9 VPAD_PITCH_HISTORY_OPEN= button 9 VPAD_SWING_NORMAL= button 1 VPAD_SWING_BUNT= button 10 VPAD_CHARGE_MOUND= button 4 VPAD_FIELD_THROW_FIRST= button 2 VPAD_FIELD_THROW_SECOND= button 4 VPAD_FIELD_THROW_THIRD= button 3 VPAD_FIELD_THROW_HOME= button 1 VPAD_FIELD_SWITCH= button 5 VPAD_FIELD_RELAY_THROW= axis+ 3 VPAD_FIELD_CUTOFF_THROW= axis+ 3 VPAD_FIELD_FAKE_RUNDOWN_THROW= button 6 VPAD_RUNNER_FIRST_SELECT= button 2 VPAD_RUNNER_SECOND_SELECT= button 4 VPAD_RUNNER_THIRD_SELECT= button 3 VPAD_RUNNER_RUNFIRST= pov90 1 VPAD_RUNNER_RUNSECOND= pov0 1 VPAD_RUNNER_RUNTHIRD= pov270 1 VPAD_RUNNER_RUNHOME2SCORE= pov180 1 VPAD_BASERUNNER_ADVANCEALL= axis- 3 VPAD_BASERUNNER_RETREATALL= axis+ 3 profile= 8BitDo_SN30_Pro device= 8BitDo_SN30_Pro player= 1 number_of_buttons= 16 number_of_povs= 1 number_of_axis= 4 VPAD_VIRTUAL_BUTTON_START= button 12 VPAD_VIRTUAL_BUTTON_SELECT= button 11 VPAD_VIRTUAL_BUTTON_CROSS= button 2 VPAD_VIRTUAL_BUTTON_CIRCLE= button 1 VPAD_VIRTUAL_BUTTON_SQUARE= button 5 VPAD_VIRTUAL_BUTTON_TRIANGLE= button 4 VPAD_VIRTUAL_BUTTON_L1= button 7 VPAD_VIRTUAL_BUTTON_R1= button 8 VPAD_VIRTUAL_BUTTON_L2= button 9 VPAD_VIRTUAL_BUTTON_R2= button 10 VPAD_VIRTUAL_BUTTON_L3= button 14 VPAD_VIRTUAL_BUTTON_R3= button 15 VPAD_VIRTUAL_BUTTON_DPAD_UP= pov0 1 VPAD_VIRTUAL_BUTTON_DPAD_DOWN= pov180 1 VPAD_VIRTUAL_BUTTON_DPAD_LEFT= pov270 1 VPAD_VIRTUAL_BUTTON_DPAD_RIGHT= pov90 1 VPAD_VIRTUAL_BUTTON_L_STICK_RIGHT= axis- 1 VPAD_VIRTUAL_BUTTON_L_STICK_LEFT= axis+ 1 VPAD_VIRTUAL_BUTTON_L_STICK_UP= axis+ 2 VPAD_VIRTUAL_BUTTON_L_STICK_DOWN= axis- 2 VPAD_VIRTUAL_BUTTON_R_STICK_RIGHT= axis- 3 VPAD_VIRTUAL_BUTTON_R_STICK_LEFT= axis+ 3 VPAD_VIRTUAL_BUTTON_R_STICK_UP= axis+ 4 VPAD_VIRTUAL_BUTTON_R_STICK_DOWN= axis- 4 VPAD_PITCH_1= button 2 VPAD_PITCH_2= button 1 VPAD_PITCH_3= button 5 VPAD_PITCH_4= button 4 VPAD_PITCH_5= button 8 VPAD_FIELD_PICK_OFF_THROW_FIRST= button 1 VPAD_FIELD_PICK_OFF_THROW_SECOND= button 4 VPAD_FIELD_PICK_OFF_THROW_THIRD= button 1 VPAD_PITCH_OUT= button 2 VPAD_THROW_BALL= not_assigned -1 VPAD_INTENTIONAL_WALK= button 5 VPAD_INTENTIONAL_HITBATTER= button 14 VPAD_PITCH_HISTORY_OPEN= button 14 VPAD_SWING_NORMAL= button 2 VPAD_SWING_BUNT= button 15 VPAD_CHARGE_MOUND= button 4 VPAD_FIELD_THROW_FIRST= button 1 VPAD_FIELD_THROW_SECOND= button 4 VPAD_FIELD_THROW_THIRD= button 5 VPAD_FIELD_THROW_HOME= button 2 VPAD_FIELD_SWITCH= button 7 VPAD_FIELD_RELAY_THROW= button 10 VPAD_FIELD_CUTOFF_THROW= button 10 VPAD_FIELD_FAKE_RUNDOWN_THROW= button 8 VPAD_RUNNER_FIRST_SELECT= button 1 VPAD_RUNNER_SECOND_SELECT= button 4 VPAD_RUNNER_THIRD_SELECT= button 5 VPAD_RUNNER_RUNFIRST= pov90 1 VPAD_RUNNER_RUNSECOND= pov0 1 VPAD_RUNNER_RUNTHIRD= pov270 1 VPAD_RUNNER_RUNHOME2SCORE= pov180 1 VPAD_BASERUNNER_ADVANCEALL= button 7 VPAD_BASERUNNER_RETREATALL= button 8
  8. Some progress! So far I've got the menu strip items working and the editor can now create a valid database (with the structures), plus the keybinds are awesome. Global and Advanced search is going to be sick. You guys are in for a treat.
  9. Jim, This is exactly the kind of real-world workflow stuff I was hoping to surface with this thread. A lot of what you’re describing lines up almost perfectly with where my head is already at especially around the idea of a Roster Audit feature: less “change values” and more “show me what doesn’t make sense before it becomes a problem.” For starters, Lahman integration is something on my roadmap. I want to make sure I do it right. One of those "measure twice, cut once" things because it has to be reliable and repeatable. Things like duplicate portrait/audio IDs, face/skin tone mismatches, and invalid pitch speeds are all great examples of stuff that technically works in the editor but quietly breaks immersion or balance if you don’t catch it. Baking those checks directly into the tool instead of relying on external scripts or spreadsheets feels like a no-brainer. This is the "well yeah, that makes sense" part of what I'm looking to build. Also, being able to import things from database to database is something I'm definitely looking at, because it could make TC projects or seasons of any kind a heck of a lot quicker to turn around comfortably. One neat little feature I want to add in honor of the work you guys do with TC is "Eras Profiles". I spoke about it in the shoutbox but basically the basic idea would be to have optional, era-aware profiles you could apply to a roster as a baseline. Things like global contact, power, stamina, pitch movement, etc., adjusted in a way that better reflects how the game was played in a given period: Deadball era, Live ball era, pre-expansion, steroid era, modern era, and so on. One important part though: this wouldn’t be about locking anything in or “auto-fixing” rosters. Think of it more like laying down the chalk lines before you start fine-tuning. You could apply a profile, see exactly what it changes, tweak from there, or ignore it entirely. From a design standpoint, I’m leaning toward keeping Eras Profiles intentionally lightweight, one solid baseline per era that reliably hits league averages for that period. TC history shows there are multiple “right” ways to balance something like pre-expansion baseball, and I don’t want to hardcode a bunch of competing recipes into the tool and pretend one is gospel. The goal, for me, is consistency and transparency: a known starting point you can trust, then adjust however you see fit. If the community eventually wants to build and share their own profiles on top of that, I think that’s a great direction. I just want the defaults to stay purposefully grounded and predictable. This is very much an idea in progress, but it feels like a natural extension of the same philosophy we’ve been talking about: making the intent clearer, reducing accidental imbalance, and letting modders spend more time on the fun parts instead of re-doing the same setup work over and over.
  10. Like how the old editor used the Lahman Database?
  11. Hey everyone, Figured it was time to finally put this out there. After being away from active MVP modding for a long while, I’ve been slowly working on a new roster editor I'm calling "MVPEdit Pro" and I wanted to start a public thread to document progress and, more importantly, get community input early rather than disappearing into a cave with a box of scraps and popping back up with a “ta-da” like I'm Tony Stark... First, some context: A quick nod to MVPEdit Anyone who’s touched MVP rosters seriously knows rglass95’s MVPEdit. It was the tool. Simple, fast, and powerful for its time, and it’s a huge part of why the modding scene lasted as long as it did. For a 2006-era Windows app, it punched way, WAY above its weight. At the same time, MVPEdit was very much a product of its era: Minimal UI structure Few keyboard shortcuts No guardrails, it basically trusted the user to know what they were doing A lot of roster “best practices” lived in forum posts, spreadsheets, or people’s heads Very unforgiving with a lack of a save feature, so a lot of your changes were "first draft, final draft" None of that is a knock at all, that’s just how tools were built back then. What MVPEdit Pro is (and isn’t) MVPEdit Pro is not about replacing MVPEdit’s core functionality or reinventing roster editing from scratch. If you’ve edited rosters before, everything you’re used to doing should still feel familiar with additional moments of "well yeah, that makes sense". This comparison lands for me and should help you understand what my intent is: MVPEdit is basically the metal cleats we were all wearing in 2006. It did the job, gave you great traction, and nobody questioned it because...that’s just what you wore back then. The problem was, one bad step and your ankle's rolled. Now you're out for the season. MVPEdit Pro (at least how I'm conceptualizing it) is going to be designed more like the modern molded cleats players wear now. Same game, same field, same fundamentals, but lighter, more forgiving, better support, and a lot easier on your legs over a long season. You’re not looking to change how baseball is played, just using better equipment for the field. Think of it as: An evolution vs a rewrite Old-school MVP logic with modern workflows The same power, but with better visibility and fewer "well, shit” moments This has been some of my guiding goals so far. My north star, pretty much: The ability to undo, redo, copy, paste and cut, etc. A cleaner, more structured UI Proper keyboard shortcuts (seriously, this alone changes everything) Better organization of tools and views Making it easier to see what you’re editing and why Giving you the opportunity to make changes and be asked to confirm them. Nothing you work on should be final until you say so (by saving). Under the hood, I’m also exploring ways to make the editor a little smarter too, not by taking control away, but by helping surface issues before they become problems. Warnings instead of hard stops. Suggestions instead of forced rules. You’re still the one making the call. Why this thread exists I don't want it to be just a progress log. I want this thread to be: A place to show what’s working and what’s still rough A place for feedback on what you actually want out of a modern editor A space to talk about workflows that were always clunky and could be better now If there are things you loved about MVPEdit, I'll do my best to preserve them. If there are things you worked around for years and just accepted as part of the old tool, I want to hear about those too. Current state The editor is still very much in progress, but the foundation is there and actively being built on. A big step the last couple of days has been cracking the historical stats table which was entirely different from the rest of the data tables in the game, but everything else is easy to translate and map within the tool as I design it, which is great because I can iterate pretty quickly. As things stabilize, I’ll start sharing screenshots and specific feature updates rather than vague promises. For now, this thread is more just about direction vs hype. If you’ve been modding MVP for years using MVPEdit or even if you’re someone who always wanted to but bounced off the tools, I’d really value your input in shaping the editor to be what it can be for all of you. Glad to be back messing with this game again. Some things never leave your system. -KC
  12. I think there's an established player ID list already though. I'm not sure why an alternate one needs to be made if it will confuse people already familiar with the existing list and could cause compatibility issues with mods. You have to think about what making an alternate ID list means in the long term, not just about what's convenient right now
  13. A note on attributes/ratings, buckets, and design intent in MVP for roster construction One thing that can trip people up when looking at MVP Baseball’s rosters is that not all ratings behave the same way. In MVPEdit, you'll see that some go from 0–99, others cap at 15, and some don’t even go past 2. At first glance, that looks messy or inconsistent. Actually, it's not. Just like with splines, this is one of those cases where EA wasn’t trying to simulate baseball pitch-by-pitch. They were trying to simulate how baseball feels over time, using math that stays stable and readable. Once you understand what each rating scale is for, the whole thing clicks. The reason an OVR number is not a thing in MVP The biggest thing to understand is this: MVP doesn’t treat ratings as raw “how good is this guy” numbers. Instead, player ratings are intended to answer two different questions: What kind of player is this? How often should that player succeed or fail within that role? Those are very different questions, and MVP uses different scales to answer each one. The 0–15 scale: defining the type of player Most core skills in MVP, things like plate discipline, fielding, arm accuracy, range, bunting, and durability ultimately resolve to a 0–15 scale internally. This scale isn’t so much about precision but classification. Think of it as the game asking “Is this an elite defender, an average one, or a liability?” and “Is this hitter disciplined, reckless, or somewhere in between?” Once the game places a player into one of these buckets, that classification stays fairly stable. A guy doesn’t suddenly become a different hitter because he gained a point or two. He has to move tiers. This is why the game will let you move up in increments of 10 up to 50, and then in increments of 5 up to 99 for the following ratings: Bunting Plate Discipline Durability Stealing Tendency Baserunning Ability Fielding Range Throwing Strength Throwing Accuracy That’s why MVP feels consistent. Players don’t randomly swing between greatness and uselessness. The 0–99 scale: weighting outcomes inside the bucket Here’s the important part, and this is where a lot of people get tripped up: the 0–99 ratings you see in menus aren’t ignored. They’re used as weights inside the bucket. So two players might both land in the same 0–15 tier, but: the one with a higher 0–99 rating will reach the better results in that tier more often the one with a lower rating will drift toward the weaker outcomes more frequently This is why a 92 and a 97 don’t feel wildly different on any single swing. Great players separate themselves over a season, not an at-bat, and elite hitters feel reliable instead of explosive. Buckets define what’s possible. Weights define how often it happens. That’s a very baseball-friendly way to think about skill, honestly. Why some ratings go to 100 A few attributes, especially Speed, and offensive ratings like Contact and Power vs handedness are treated differently and go all the way to 100. That’s because these affect things that need smooth, continuous movement: how fast a player runs how much ground they cover how far a ball travels Speed in particular touches everything: baserunning, steals, defense, recovery. Those systems benefit from finer granularity, so EA let them behave more like true analog values. The 0–2 scale: tendencies, not talent Team and manager tendencies (steal, hit-and-run, bunt, pinch hit, intentional walk) use an even smaller scale: 0–2. This isn’t about ability at all. It’s about preference. Think of it like this: 0 = avoids this 1 = neutral / situational 2 = looks for this opportunity EA wasn’t trying to model managerial genius here. They were encoding identity. A lot of datafile blocks combine small preference flags with player traits and situation, instead of relying on a single “smart” decision. EA's design intent: Just like splines, this approach lets EA balance a lot of competing goals: Players feel different without being chaotic Ratings matter without dominating outcomes Small changes don’t break the game Seasons feel realistic instead of streaky The game stays readable and fair Most importantly, it avoids a trap a lot of sports games fall into where one rating point should never decide a baseball play. So with MVP it was a smart design choice where, ratings don’t decide outcomes, they just nudge probability. It also explains why they never designed the game using a numeric OVR system: it’s an honest reflection of how MVP evaluates players as profiles and tendencies rather than exact point totals. How this ties into the gameplay blocks Once you understand buckets and weights, the rest of the datafile will begin to make sense: <cpubatter> uses buckets to decide if a swing makes sense <batterai> assigns a contact-quality tier, weighted by ratings <batter> expresses that tier within capped, controlled ranges <pitcher> defines reliability curves, not dominance <hitnrun> blends preferences, ratings, and context into tactics Every system is speaking the same internal language. The quiet brilliance here Put all of this together and you get a really clean design throughline: Buckets instead of raw stats Weights instead of guarantees Splines instead of linear decay Bars instead of fake precision Even when it's all math under the hood the game still *feels* like baseball.
  14. Next chunk I found is called <stealtune>. <stealtune> — “Should we run here?” <stealtune> is the CPU’s steal attempt filter. It doesn’t decide the physics of the jump, the catcher’s pop time, or tag windows. It decides whether the CPU even tries, by stacking situational “common sense” rules with a few player-tool buckets (speed/steal vs catcher/pickoff). Think of it like a manager’s clipboard: “With this count, this runner, this catcher, this pitcher… are we running or are we staying put?” EA's design intent: Based on the stock values, EA was trying to make stealing: Rare for slow guys (hard “no” gate) Only modestly encouraged for elite thieves (small positive boosts) Heavily suppressed by strong-armed catchers (big negative) Less common in “wrong” situations (2 outs, 2 strikes, big score diff) Predictable enough to feel fair (so the CPU doesn’t look psychic or cheesy) It’s conservative by design. EA wants steals to exist, but not dominate pacing. What <stealtune> is responsible for How often the CPU attempts steals How strongly runner tools matter (Speed + Steal) How strongly battery tools discourage attempts (Pickoff + Catcher arm/accuracy) Situational suppression (outs/strikes/base/handedness/score) A baseline/team tendency (ManagerRating) How <stealtune> works Each time the CPU considers stealing a base, it starts with a neutral “urge,” then applies modifiers: Situation penalties (global “don’t be dumb” rules) Runner bucket modifiers (Speed + Steal skill ranges) Battery bucket modifiers (Pickoff + Catcher arm strength/accuracy ranges) Score context penalties (stop running in blowouts) ManagerRating baseline tendency The output is basically: green light / no green light. Situation penalties (flat, always applied when the condition is true) 2Outs_R1st = -30 With 2 outs and a runner on 1st, EA strongly discourages stealing. Intent: avoid “erase the inning” outs and keep offense flowing. 2_Strikes = -10 With two strikes, discourage steal attempts. Intent: don’t run into outs when the batter might K anyway. R2nd = -20 With a runner on 2nd, discourage steal logic (usually affects double-steal style behavior / unnecessary risk). LHP_R1st = -20 Lefty pitcher with runner on 1st is treated as riskier (lefties hold runners better on average). RHP_R2nd = -20 This is a bit more “engine-specific,” but intent is still clear: a certain handedness/base context combo reduces attempts. Translation: EA bakes in “baseball common sense” as negative modifiers so the CPU isn’t reckless. Speed buckets (the big gate) SpeedMin = 0.85 SpeedMax = 1.00 SpeedMod = +10 This means: if the runner’s speed is in the top bucket (0.85–1.00), the CPU becomes more willing to run. SpeedLowMin = 0.00 SpeedLowMax = 0.63 SpeedLowMod = -100 This is not subtle. This is EA saying: “If you’re slow, you are basically forbidden from stealing.” Probably one of the strongest “anti-cheese” guardrails in the entire datafile. Steal rating buckets (Low/Med/High) Steal A (low skill) StealAMin = 0.00 StealAMax = 0.64 StealAMod = -3 Steal B (mid skill) StealBMin = 0.79 StealBMax = 0.89 StealBMod = +3 Steal C (high skill) StealCMin = 0.90 StealCMax = 1.00 StealCMod = +6 Notice the gaps: 0.65–0.78 isn’t defined here. That usually means those values fall into a “neutral/no modifier” zone. What does this mean? Elite steal ratings help, but they’re not allowed to overpower the rest of the logic. Pickoff threat buckets (pitcher holding runners) Pickoff A (weak hold) PickOffAMin = 0.00 PickOffAMax = 0.50 PickOffAMod = +5 If the pitcher is bad at holding runners, stealing becomes more attractive. Pickoff B (strong hold) PickOffBMin = 0.90 PickOffBMax = 1.00 PickOffBMod = -5 If the pitcher is elite at holding runners, attempts drop. EA keeps this as a light nudge (+/- 5), not a hard gate. Catcher arm strength buckets (big deal) Weak arm (run on him) CatcherArmStrAMin = 0.00 CatcherArmStrAMax = 0.50 CatcherArmStrAMod = +5 Strong arm (don’t run) CatcherArmStrBMin = 0.90 CatcherArmStrBMax = 1.00 CatcherArmStrBMod = -15 This is the strongest negative besides SpeedLowMod. EA is basically saying: “Catcher cannon matters more than almost anything else.” Catcher arm accuracy buckets (secondary) Inaccurate throws encourage running CatcherArmAccAMin = 0.00 CatcherArmAccAMax = 0.50 CatcherArmAccAMod = +5 Accurate throws discourage running CatcherArmAccBMin = 0.90 CatcherArmAccBMax = 1.00 CatcherArmAccBMod = -5 EA weights accuracy less than strength, which makes sense. Score differential suppression (pacing / realism) ScoreDiffA ScoreDiffAMin = 5 ScoreDiffAMax = 9 ScoreDiffAMod = -30 ScoreDiffB ScoreDiffBMin = 10 ScoreDiffBMax = 100 ScoreDiffBMod = -50 Translation: in blowouts, stop running. EA is protecting pacing and “sportsmanship” feel. Manager/team tendency ManagerRating = 17 This is almost certainly a baseline aggressiveness/tendency scaler used by AI teams. You can think of it as “default green light tendency,” then everything else pushes it up or down.
  15. So, for our next block we're going to cover another block called <cpubatter>. <cpubatter> - the brain of the AI hitter The <cpubatter> block governs how the CPU decides to swing. It does not control player ratings, swing animations, bat speed, or ball physics. Instead, it defines the CPU hitter’s perception, judgment, and confidence at the plate. In practical terms, this block answers questions like: Does the CPU think this pitch is hittable? How confident is it in swinging at what it’s seeing? How much does pitch location matter? How does the count influence aggressiveness? How wrong is the CPU allowed to be? If ratings describe who the hitter is, <cpubatter> describes how that hitter thinks during the at-bat. <cpubatter> operates blind to contact outcomes though. It only evaluates whether a swing is justified, not whether it will be successful. EA's design intent: EA was not trying to build a true simulation of human pitch recognition or hitter psychology. The goal was to create a CPU batter that feels believable, fair, and consistent, while remaining scalable across difficulty levels and stable on mid-2000s hardware. Rather than using deterministic physics or advanced AI, EA relied on probability weighting, zone-based confidence, and controlled error to simulate decision-making. EA’s intent: Keep CPU behavior predictable but not robotic Avoid unfair or omniscient CPU hitting Preserve game pacing (fewer 12-pitch at-bats, fewer extreme outcomes) Make difficulty adjustments possible without rewriting logic Ensure results feel earned rather than scripted The result is a system that creates the illusion of intelligence through math, not true awareness. What <cpubatter> is responsible for The <cpubatter> block controls the decision-making layer of hitting. Everything here happens before contact, power, or ball trajectory are calculated. Specifically, it governs: How accurately the CPU “reads” a pitch How much pitch speed and movement can fool the CPU Whether the CPU decides to swing or take How pitch location affects confidence How count and situation influence aggression How much human-like error is allowed This block does not determine how hard the ball is hit or where it lands, only whether the swing attempt happens and how confident the CPU is that its timing window is acceptable to swing. Strike Zone Context (Hot/Warm/Cold) All Hot, Warm, and Cold references in this block refer strictly to strike-zone quadrants, not player streaks or momentum. The game divides the strike zone into a 3×3 grid, and each pitch is evaluated based on where it crosses that grid. Hot zones = areas where the hitter is strong Cold zones = areas where the hitter is weak Warm zones = neutral or average comfort These values adjust how confident and aggressive the CPU is when the pitch passes through those zones, especially when combined with count and discipline logic. The hot and cold zones influence willingness to swing, not contact quality or power. How the CPU Batter "Thinks" Pitch Recognition The CPU does not see the pitch perfectly. Instead, it predicts the pitch path with built-in uncertainty.. EA’s intent: Fast pitches should be harder to read Breaking pitches should occasionally fool the CPU Prediction error should scale with difficulty The CPU should sometimes act with confidence despite incomplete information This creates swings that look early, late, or poorly judged without feeling random. Discipline and Swing Decisions Once the pitch is “seen,” the CPU decides whether to swing. EA’s intent: Prevent constant chasing of bad pitches Keep walk totals reasonable Avoid overly patient CPU hitters Make count matter without stalling the game This is where plate discipline lives, not as a rating, but as a behavior filter layered on top of pitch recognition. Contact vs Power Bias The CPU is not always primarily swinging to do damage. In this block, EA intentionally biased the system toward contact over power to: Increase balls in play Reduce empty swings Create more organic rallies Avoid arcade-style outcomes Power is still present, but since this is the first block in the hitting model, it's handled downstream in <batter> and <batterai> Timing Confidence and Error Tolerance Even correct decisions can produce imperfect swings. EA’s intent: Allow early and late swings Prevent perfect timing every pitch Add natural variance to outcomes Avoid repetition in contact results This keeps the CPU from feeling mechanical or unfair. Tuning Considerations This block is safe to tune when adjustments are made with intent and restraint. High-impact tuning areas: Hot vs Cold zone confidence gaps Discipline behavior in hitter’s vs pitcher’s counts Pitch recognition error on high velocity Protection behavior with two strikes Areas to adjust carefully: Global swing decision values Prediction blending values Overall contact or power bias Small changes here can dramatically alter CPU behavior. Final Notes: The <cpubatter> block is best understood as the CPU’s eyes and judgment, not its strength. EA designed this system to preserve pacing, protect fairness, simulate intelligence without true AI, and funnel outcomes toward believable middle ground. Contact quality is evaluated later by <batterai>, and final outcomes are shaped by <batter>.
×
×
  • Create New...