Developer Notes 6.26.26 - Play To Clinch Tennis Sim

A stretch of work that mostly came down to one idea: stop hard-coding who's good

Made some QOL improvements to the post-season tournament, added to the data portal

Building a fog of war team tennis simulation for yourself means that when it's ready to play, it's ready to play. PTC has been playable for a bit, but most of my work lately has been testing to find things I want to mod. The first of those big changes was with the post-season tournament logic.

The four meaty ones each got their own write-up, so here I'll keep it to the elevator version and let the deep dives do the talking.

Prestige stopped being permanent. Program prestige wasn't hard coded, because I have an editor to make changes. But it did get sort of dictated by whatever conference you were in. I didn't like this for future state, when I play longer if a mid-major has a run I want them to be able to enter the major ranks. So now, it drifts every offseason based on how a program performs against its own expectation, so a small school that keeps overachieving climbs the ladder and a coasting name brand slides down it. I

The selection committee became four numbers. The D1 tournament is 96 teams, up from 64, and there were too many upsets. The reason: the bracketing logic was ranking teams 1-96 and it was giving automatic qualifiers a direct pass into the Top 24 no matter what conference they were in. As much as I love an egalitarian bracket, this was wrecking my sense of virtual tennis sim reality and I needed to fix it. LLMs are generally terrible at bracket logic, they don't get it. So I had to essentially spell out the entire details of how the NCAA basketball tournament gets bracketed, so the LLM course use that format for my tennis nationals. I opted for doing it basketball's way instead of how tennis does it, largely because I prefer seeing a tournament that feels more March Madness-like. Plus, with a computer simulation, it would've pitted too many teams who are top tier against each other.

Recruiting became a budget. Programs no longer carry a flat scholarship count. They haven't for a while in this game, though. I had everyone with 6 scholarships in D1, but they were "valued" differently if you were a blue blood or a major versus a low or mid-major. The way of doing this kept me from having to introduce messy budgets and track them -- this is just a game for me, after all -- and felt like a semi-elegant way to produce the NIL era. Blue chips are worth more than 5-stars and 1-stars are free.

I noticed even in this format, elite D3s weren't getting the kinds of players they should be -- then I took the UAA and top tier D3 programs and moved them to D1 (because I could) -- and then I split D3 into two

Regionalizing the bracket. This is kind of the 1B to the major work to change the way we seed the tournament. In D1, it's 96 teams and in D2-D4 it's 64 teams. The 96-team top-division field now splits into four S-curve regions that are balanced by strength to the exact point total, with byes, a regional play-in, and region champions (Final Four teams) meeting in the semis.

Essentially, what you get in D1 are 24 seeds instead of 16 per regional and there are 4 regions. The other thing I did -- purely for cosmetic reasons -- is name all 4 regionals. But I'm extra, so rather than naming them East, West or whatever, I took the entire league list from Learned League and a randomizer chooses them for each division, annually. Why did I do this? I don't, because it was easy and fun? Yeah that's why.

The smaller stuff that filled out the rest of the list:

A lineup lab. I wanted to be able to see by conference how teams were stacking each other. So I took what the UTR site does for the sim, you can look at each lineup 1 singles through 6 singles and see where their STR (our version in-game) is relative to the rest of the conference. I did this partially because most of the fun of this game is finding hidden talent and seeing how they perform. I already have a data tool that tells me where talent are undermatched relative to their league, but this data is a lot more fun to look at this way. Truly realistic and over the top at the same time.

The prestige journey, made visible. Once prestige started moving, I needed to see it move, so the data hub now lists every program with its prestige as a base → current journey and the tier change spelled out. Sim a few years forward and you can watch a mid-major physically climb out of its tier, I haven't done that yet, but it'll eventually show here.

I'll probably share the longer form articles for each one of these changes at some point, I think like with the baseball sim and Viperball sim, knowing what I was trying to accomplish, being able not just to be opinionated about directing an agent, but knowing what tools make sense for the job, being precise about the spec and when testing knowing what you're looking for makes stuff like this work a lot better.

If I cared more about the actual tennis realism, I'd probably be more curious to test scores and make sure they're realistic, but the underlying python sim is actually a lot more mature than anything in the other two games, partially because unlike Viperball and O27, this was the first sim I built of a sport that I didn't distort into a new fictional sport. O27 obviously has a baseball undergrid and Viperball a gridiron football one, but when you're inventing the rules of the sport, there's just a lot more novelty that goes into your design decisions to get it right.