I let the win rate decide the default difficulty
The default difficulty for solo bot games in TAMNA was Mid, and I had nothing to back that up with. A default is the value that stays where it is as long as nobody does anything about it, and the fact that it stayed there is not evidence that it was right. On this day I finally counted the production data properly, and then changed the default. What I changed was not how strong the Mid bot is. It was only which difficulty gets handed to somebody who chose nothing. Here is what the numbers decided, what I deliberately left alone, and the side effect that leaving it alone leaves behind.
Written: 2026-08-01
A default is the opponent that people who chose nothing get
There are two doors into a difficulty setting in TAMNA. You can create a room and pick a level for each bot seat, or you can skip all of that and use quick play. Even at the first door, a seat you never touch has no value in it, so both doors need a value to fall back on when nobody chose. That is the default.
A default looks like one setting among many, but I take it to be the value that quietly settles more games than any other in the system. Anybody who opens the settings and makes a choice already knows their own taste by the time they do it. The default lands on people who do not know yet, or who do not want to spend attention on the question. So a default is an opponent I am assigning silently, and if I have assigned the wrong one, the player has no way to see it as anything other than what this game simply is. Which means nobody checks whether the default is right unless I check it.
The trouble is that I cannot measure that with my own hands. Whoever wrote the bots knows what they look at and what they ignore, and that knowledge does not switch off while a game is running. How a Mid bot feels to me is not evidence of how it feels to somebody arriving for the first time. The default, of all values, had to be decided by something other than my instincts.
I looked at the win rate, not at how it felt
I audited the production data and pulled out only the games with one human and three bots. The human side was winning 54% of those. If four players were evenly matched, each of them should settle near 25%. Fifty-four is more than double that. It means beating three opponents at once in better than one game out of two.
What that number was saying was not ambiguous. The default Mid bot is plainly weak as an opponent for somebody who is playing seriously. That Mid was sitting in the default slot and that Mid deserved the default slot turned out to be two different claims. The distance between 25% and 54% is not a gap you close by adjusting an impression.
It is worth writing down what the number cannot do, too. Fifty-four per cent is an average, and averages erase the people inside them. Someone who has just started and never won a game and someone who walks straight through Mid are both dissolved into that single figure. So I read it as telling me not to raise the default one step, but to stop handing everyone the same default at all. The default should not be one fixed value; it should be chosen from what that particular player has already done. I put the boundary at what I judged to be a low bar: two wins in games played alone against the bots. Below that, Mid stays the default. Above it, Hard becomes the default.
I did not touch the difficulty constants
The shortest fix available was to make the Mid bot think better. I did not take that route: not one line of the constants that define how the bots decide was changed. My own guess is that sharpening Mid would move the number somewhere, but I never measured how far, so I do not actually know. The reason I left those constants alone sits somewhere other than the size of that effect.
The reason is that those constants are what the difficulty names mean. Strengthening Mid also changes the opponent for everyone who chose Mid on purpose. Those people asked for Mid; they did not ask for something slightly harder wearing the Mid label. Easy, Mid and Hard are a promise made to the person playing. Shift the contents while leaving the labels in place and you quietly break both the spacing between the three steps and whatever intuition that player built up in their last game.
So I changed the assignment rule instead of the difficulty itself. Mid is still Mid and Hard is still Hard. The only thing that moved is which of the two gets handed to a player who chose neither. Keeping the two apart has a practical benefit as well: if this judgement turns out to be wrong, there is exactly one place to revert, and the games of everyone who has been picking their own difficulty were never affected in the first place. A change to a default is safest when it is fenced in so that it cannot leak outside the default.
A choice somebody made is never overwritten
The adaptive part only runs when, at either door, nothing was chosen. If a seat has an explicit difficulty on it, that value is what gets used. Easy is included in that. Somebody with a pile of wins who selects Easy does not get quietly moved up.
I put that rule ahead of the feature itself. A win count is a serviceable stand-in for skill and nothing more; it says nothing whatsoever about what a person wants out of the game they are opening right now. They might be showing the board to a friend. They might just want to look at how something renders. I have no way of knowing, and there is no justification for guessing at the thing I cannot know and using that guess to override a preference somebody stated out loud. The only place automation is allowed to decide is the place where nobody said anything.
Put another way, this feature has authority to fill in a blank field, not to correct a field that is already filled in. In my experience, systems that try to be clever tend to lose people at exactly the moment they start doing the second one. Improving a default is only worth doing on the condition that an explicit choice always wins.
What I chose not to store, and the side effect that remains
The implementation counts a player's past solo wins against bots from the existing game records, at the moment it needs them. No new column was added and no migration was run for it. Everything the adaptive rule needs can already be derived from records that are being kept anyway, and copying a derivable value somewhere else gives you two versions of the truth. From the first time an update is missed, the basis for how strong the bots are goes on living quietly at an old value while everything else moves on. I would rather pay to recount it every time.
Games abandoned in the opening are left out of that count. Counting a game that ended almost as soon as it began mixes in something that has nothing to do with whether a person played seriously. What I was protecting there is less accuracy for its own sake than this number's right to stand in for skill at all. Add up wins that do not qualify and it stops mattering where you draw the boundary.
One thing is not resolved. With this design, the opponent changes in the game right after a player crosses the boundary. To somebody who has never opened the settings, it must look as though they did nothing and the opponent changed by itself. How that actually felt is not something I can see from my side; the individual people standing outside the average are exactly what a win rate does not report. Still, when an assignment rule moves without being asked, publishing the rule is the least the person who wrote it owes. This entry is part of that publication.