SotA

The New Britannia Herald

Saturday, August 1, 2026

Work Log Podcast

Episode

Two hundred bots, a switched-off lever, and stealth that finally hides you

Saturday was the day the crowd test finally worked, and it found two pieces of code whose cost grew with the square of the player count plus an entire cheap-simulation system that had been commented out for longer than our source history goes back. Stealth stopped drawing a shimmering outline of every hidden character, and creatures can now lose you when you break line of sight. Plus the Chaotic Clone stopped introducing itself, a single player report on a Linux laptop uncovered texture streaming being off everywhere, and every window in the game learned to hold a little glass.

In this episode

  • Two hundred test bots and the crowd performance hunt
  • Stealth, line of sight, and the new smoke bomb
  • The Chaotic Clone stops giving itself away
  • One Linux report uncovers texture streaming switched off
  • Window themes, glass, patterns and per-window opacity

Transcript

Good evening to thee, citizens of New Britannia. Lord British here, with an accounting of what thy makers were about upon Saturday. Two hundred souls were made to stand within a single hall, and the hall told us plainly which of us was the weaker. The rogue who hides is at last hidden, from wolf and rival alike. A conjured double has ceased introducing itself by name. Every window in the realm has learned to hold a little glass. And somewhere deep in the machine we found a lever that makes the world faster, switched off so long ago that no record survives of the hand that did it. We shall begin there.

Picture two hundred people standing in Castle Atos on Saturday morning. They are in the player list. They are setting off fireworks. And there is nothing there. No bodies, no faces, just names and explosions coming out of empty air. Those were our test bots, and they had been haunting the place for a while, because a character that never says where it is standing gets filed at the centre of the map underneath the terrain, and one that never says it finished loading is somebody nobody bothers to build a body for. Two small confessions later, the ghosts became a crowd.

That crowd is the whole point. We have been building toward a proper stress test of the game client for weeks, and the honest reason is that we want a dance party. A hundred and fifty people in one room with the fireworks going, still dancing, still able to see each other. Large fights get the same benefit, but the dance party is what is pinned above the desk.

So we ran the bots up from ten to two hundred in a single town. The server barely noticed. It sat around ninety four percent idle, and each extra character cost it about a sixth of one percent of a processor core. The thing that fell over was the client, pinned to a single thread while the graphics card sat there with almost nothing to do. A server-only test would have reported that everything was fine.

Then we stood in that crowd with a profiler running, and found two pieces of code whose cost grows with the square of the crowd. Double the players and you quadruple the work. The first was a lookup that walks the entire list of everyone in the scene every single time it is asked which player something belongs to, sitting behind something that reads as free to call, so it ended up running for every character every frame. At a hundred and fifty players that came to roughly forty eight thousand reads of the player list per frame. Per frame. It is a direct lookup now.

The second was subtler and rather more human. Every character searches for who is standing near it, and that search is meant to run about once a second. The copy that runs for your own character was correctly limited. The copy that runs for everybody else's character had no limit at all, and ran every frame. Somebody wrote the careful version once and the careless version once, and it was the careless one that got handed to a hundred and fifty avatars.

We measured again on a build carrying both fixes. Same scene, same viewpoint. The script work the client does for the crowd fell from about fifty milliseconds a frame to thirty nine, and the saving grows with the crowd the way the shape of the bug predicts. We had predicted a saving of nine point six milliseconds at a hundred and fifty players. We measured eleven. When the arithmetic and the stopwatch agree that closely, it means somebody actually understood the problem.

And then the good part. Buried in the client is a complete system for simulating distant players cheaply. Distance tiers, real thresholds, half a dozen places that branch on it. All configured, all correct, and the one call that drives the whole thing was commented out. Every remote player in the world has been running at the most expensive setting no matter how far away they were standing. We cannot tell you who switched it off, or why, because the comment-out predates our copy of the source history. It has been off for longer than we can see.

We turned it back on, and then we made it better. The original design cut players off by distance, which bounds how far away someone can be and says nothing at all about how many of them there are. Everyone inside about fourteen metres counted as close, so a packed tavern still ran the expensive path for the entire room. It now also caps the number, nearest first. The cost of standing in a crowd of five hundred is the cost of standing in a crowd of fifteen.

A review caught the problem with that one before it went anywhere near you. Switching off a distant player's physics also takes away the invisible shape that area effect abilities search for when they hunt for targets. So casting a fireball into a packed square would have found the dozen or so people nearest you and quietly missed everyone else, who would have stood there watching the fire go round them. The cap now covers the expensive movement work and leaves that shape where every query can still find it.

Now let me tell you about stealth, because this one is embarrassing, and it is my favourite thing we shipped all week.

When you went into stealth, your body was correctly dissolved away. And then a second piece of code came along behind it and drew the same shape straight back for every other player, as a shimmering, body-shaped outline that followed you exactly. The hiding worked perfectly. Something else traced you in the air afterward. There is a distortion strength involved that was authored at thirty against a code default of one half, so if anything we had rendered you rather emphatically. For years, stealth has been an excellent way of announcing your position while looking like you meant to.

Other players now see nothing at all unless they are within about three metres and facing you, which is the same range at which they could already target you. Party members still see you. Stealthed creatures keep their faint shimmer, so an ambush still reads as an ambush. Two more came out of tracing that one: a stealthed player could be moused over and clicked from any distance at all, because the cursor path had never had a stealth rule in it, and stealth ending during a zone change used to leave that character's lights switched off permanently. Wandering the world in a personal eclipse.

Then the bigger one. Breaking line of sight while hidden has never worked. Not once, not ever. A creature that had already spotted you kept a shortcut in its head that went, I have seen this one, I can see where it is, carry on. That shortcut did not consult stealth in any way. So you could duck behind a wall, into a bush, into a barrel, and the bear simply knew. The entire promise of the skill is that you can get away, and the getting away was the one part nobody had wired up. Break line of sight and hide now, and whatever was chasing you loses you.

Camouflage deserves its own moment. Its description promises that Subterfuge Specialization raises your maximum stealth level, and it delivered precisely none of that, because it was reading the Tactics specialization instead. It was the only skill in the whole tree pointing at the wrong number. It came to us reported as a tooltip bug. The tooltip had been telling the truth the entire time and the data underneath it was fibbing.

Two more from the same pass. Sneak Attack had no weapon requirement and used your weapon's range, so an archer got the full stealth opener from bow range with none of the risk of walking up to somebody. That is melee only now. And Riposte and Opportunity Strike both describe themselves as following immediately after a parry or a dodge. Riposte's window was eleven and a quarter seconds at high Blades, and Opportunity Strike's armour-bypassing bonus was guaranteed for about eleven. Immediately now means two seconds. Damage is untouched until we have all played with the shorter windows.

And there is something new in the tree. Obfuscate throws a crafted smoke bomb and hides you sharply for a couple of seconds, out in the open, even while something is actively hitting you, which is exactly the window you need to break line of sight and get back into hiding. Smoke Bombs are an alchemy recipe, three to a batch. It takes the slot Pugilism vacated, because Pugilism has moved to Tactics, where its description had quietly claimed a Subterfuge benefit that the numbers never once provided.

Next, the Chaotic Clone. If you have not met one, it is a decoy. You cast it, it looks like you, and the idea is that whoever is trying to kill you spends a few valuable seconds killing the wrong you.

Here is what it actually looked like. Its name plate printed your name twice, once plain and once in angle brackets, which is precisely where a guild name goes. So it stood there presenting itself as you, of the guild called you. No title line. Name drawn in the colour we reserve for monsters. It wore every piece of your outfit including the helmet and cloak you had deliberately hidden, because the code deciding what to draw asked whether the thing was a player, and drew absolutely everything when the answer was no. The weapon stayed out permanently, which is what a summoned creature does and no avatar does. It ran slightly slower than you, so the pair of you drifted apart as you ran. It carried twenty eight hit points, so the moment anyone hit it, the numbers under its name read fourteen out of twenty eight beside your fourteen hundred. And if a rival was somehow still fooled after all of that, right-clicking it opened a pet sheet.

One click. That was the entire deception.

What I like about the fix is that it is one idea rather than nine. There is now a single question the game can ask about anything in the world: which player is this presenting itself as? A player is itself. A clone is its caster. Everything else is nobody. The name plate, the party typeface, the guild leader and grandmaster marks, the checks that decide which pieces of your outfit get drawn, and the right-click menu all read through that one answer. Combat, aggro and pet ownership deliberately do not, so a clone is still a summoned creature everywhere the rules are concerned. It takes your health pool now, matches your run speed, sheathes its weapon when you sheathe yours, and follows your title, your guild and your flags for as long as it lives. Join a guild with a clone standing next to you and the clone joins too.

A player wrote to us about poor performance on a laptop running our Linux client. That single report turned into the most useful measurement we have taken this month.

Our telemetry happened to contain the same physical machines running under both Linux graphics drivers, which makes it a controlled comparison rather than a guess across different hardware. Seventeen hundred samples. Under OpenGL those machines averaged twenty five frames a second and seventy eight milliseconds of processor time per frame. Under Vulkan, fifty eight frames a second and under twenty milliseconds. Four times the processor cost for identical work. The Linux client now starts on Vulkan. Anyone who already picked a graphics option in the launcher keeps their choice, OpenGL stays selectable, and it remains the automatic fallback if Vulkan will not start. Windows and Mac are untouched.

That gap hid for so long because our frame rate report recorded which graphics chip you had and never which driver was running. You could work it out from suffixes on the renderer name, if you knew to look. Nobody knew to look. It records the driver now.

The same investigation opened a much bigger door. Texture streaming was switched off on every quality level in the game. All seven. So the client uploaded every texture at full detail with no memory budget of any kind, while a perfectly good memory budget sat in the settings right next to the switch, doing nothing whatsoever. That is why one Linux session logged thirteen thousand one hundred and eighty four low-memory complaints from the graphics driver and then sat at eleven frames a second. The giveaway is that the processor and graphics timings read the same number, which looks in the charts like a processor bottleneck and is nothing of the kind. That is the processor standing in a queue inside the driver, waiting.

Streaming is on now, with a budget per quality level and a ceiling worked out from the machine you are actually sitting at, and three thousand nine hundred and sixty four world textures were swept onto it. Interface art and a few other categories are left out on purpose, since menu art parked at its lowest detail is simply blurry menus.

One more from the same afternoon. A fresh install now picks its starting video settings from the machine it finds itself on. Until Saturday the client read your graphics chip purely so it could write the name into a log file, and then started a top-end desktop and a thin laptop on exactly the same preset. We also found that the automatic quality adjustment had a condition that could never be true, so distant ground detail has never once been turned down on a struggling machine, across all the years that shadows and detail levels have been quietly adjusting themselves. Its trigger only fired below twenty five frames a second as well, so anyone sitting at thirty to forty five got no help. It now aims at a target worked out from your own frame rate limit.

Now something purely for pleasure. Windows. Every themed window in the game has been retuned toward glass. The dark themes went from ninety six percent opacity down to eighty, popups to eighty eight, and Classic stepped down as well, so more of the world reads through your interface while the text stays legible. New tests composite that text over worst-case scenes and check the contrast, because glass is charming right up until somebody cannot read their spell names.

The corner ornaments grew into a proper choice. A new quiet default called Quill keeps the engraved flourish on the bottom corners and puts a small tapered line with a floret up top, so the close and pin buttons stop sitting on dense filigree. The old full filigree is still there as Flourish. There is a new thin double-line frame with corner diamonds called Rail. Or you can turn corner art off entirely, on any theme, including Classic, which never had any. Window backgrounds can carry a texture as well: Parchment, Leather, Smoke, a centred chaos star watermark, or Glass. Those patterns are derived from the game's own book and window art, so they belong to this world rather than to a stock texture pack.

Then the one I did not expect to enjoy so much. Right-click any window's title bar and you get a small opacity slider for that window alone, from fifteen to a hundred percent, with a reset button. Chat can run glassier than your inventory. It saves per window and stacks with your theme. There is a Reset Window Layout button in Options for when it all gets away from you.

The theme editor itself was rebuilt, and I want to confess what it used to do. It had never been put on the shared window frame, so it did not remember its position, it did not clamp to your screen, and it leaked gameplay keys. Dragging a colour slider would walk your character across the room and fire your hotbar. You would look up from choosing a nice shade of blue to find yourself somewhere else entirely, casting. It also threw away unsaved edits every time you returned to the login screen. It stashes your working theme automatically now and hands it back next time you open it, after a crash included. And it opens on a new Simple view where you pick an accent colour, a text tone, a surface and opacity, a pattern, an ornament style, fonts and motion, and it derives the full set of forty nine colours from that. The old list of all forty nine lives on in an Advanced view, with a search box and a visible selected row, which it never had.

A handful of smaller things that will improve somebody's evening. Resetting a character's quest state used to erase every map and arrival point that character had discovered, because discovered places live in the same list as quest flags and the reset rebuilt that list from a short keep-list. So a reset character could not travel anywhere it had already been. Places you have found now survive the reset. Journal entries and quest flags still clear, as they should.

Three things about your bags. Container windows no longer open exactly on top of one another. Open a chest, a bag inside it, a bag inside that, and you used to get three windows on the same pixel with only the front title readable. Each one now steps down and to the right, and closing a middle one puts the next one you open back in that gap. Highlighted rows now belong to one window at a time, so a bag, a chest and your backpack can no longer each hold a selection with nothing to say which one an action would use. That came from a tester who also proposed the fix, which is my favourite kind of report. And searching all your stuff reaches your bank from anywhere now, with no trip to a banker first.

The encumbrance warning in the corner now appears the moment you go over your carry capacity. On the new interface it had been staying hidden until you were roughly two and a half times over, so through most of the range where you are already slowed to a plod there was nothing on screen mentioning it. The exclamation mark is yellow as you approach the weight that stops you picking anything up, and red once you reach it. The conversion had carried the mark across and left its colour behind.

Partner dancing had a lovely bug. Ending a dance only broke the pairing between the two of you, and the waltz animation loops forever with no natural finish, so you kept dancing. Nothing checked whether your partner was still dancing either, so if they stopped an arm's length away, you waltzed on alone with nothing to tell you. A dance now ends for both people when either one moves, stops, drifts about seven and a half metres away, or logs out, and you both get told. There is a slash partner off command now, which used to answer that off was not nearby, as though off were somebody's name.

And the Options window's Controls tab has a search box. A tester went looking for one and reported it missing. It had never existed, in this interface or the one before it, but the list runs to close to two hundred actions so the report was right about what ought to be there.

Everything else, at speed. Forty eight tracker items were closed on Saturday. Two hundred and forty two leftover build warnings were cleared out of the editor, and one of them had been covering a real bug where the compass strip and the map picture were lined up twice over, so on some machines the wrong slice of artwork got drawn. Eighty four editor dialogs that existed purely to announce a job had finished, and to stop everything until somebody clicked them, write a console line instead now. The failure dialogs stayed, since those are worth interrupting for.

Our own tools took some knocks. The profiling report had been adding up work across all fifty six threads at once, so it cheerfully reported seventeen thousand milliseconds of work inside a frame that was a hundred and sixty four milliseconds long. It now accounts for the frame exactly, which retires an old question about a third of the frame being unattributed. Nothing was ever missing. We had been subtracting wrong. We also caught a test that was passing without testing anything, because it needed a live connection that does not exist when tests run, so every case skipped and the run reported success. A suite that reads green while testing nothing is worse than no suite.

A tester reported their map marker sitting slightly off the trail they were standing on, so rather than argue about it we built something that measures the question directly, putting an object at a known spot and comparing where it lands against where the map claims it should be. That zone came back accurate to six centimetres, so the map is exonerated and the hunt moves to the client. And our Game Masters got a proper summon window with the whole monster library in it, since the only previous method was typing one of one thousand three hundred and seventy six paths into a console that release builds do not even contain. Creatures summoned for events can no longer be tamed, which had been making them free maximum-tier pets, and dying to event monsters no longer counts against you as a player kill.

That was Saturday. One report from one player on one laptop turned into a graphics investigation that helps every machine we ship to. Two hundred fake people stood in a castle and told us the truth about our own client. And a rogue can finally hide behind a wall and mean it. What I am looking forward to is the day somebody stands in a room of a hundred and fifty with the fireworks going and notices nothing at all. That is the highest praise this kind of work ever gets.

I did ask the team how, after all these years, they finally caught the stealth bug. They said it had been standing right there in front of them the whole time. Of course it had. That was the bug. Good night, friends.