Development covered 15 Aug 2026 to 17 Aug 2026 (commit dates).
Players of Myriad Immortal Sect walk a continent that streams in around them as they go. It had felt slightly rough for weeks, in the way that is easy to live with and impossible to un-notice, and I had two confident theories about why.
Both were wrong. I finally measured, and the number that came back was 1,826 draw calls to put 61 objects on the screen.
Loading and showing are different units
The map loads in chunks. A chunk is a sensible unit for loading, because it is a sensible unit for unloading: when you walk far enough away, the whole chunk goes.
The problem is that the renderer does not skip a plain image just because it sits outside the view. Every loaded thing gets submitted, every frame, whether it is in front of you or twenty eight thousand pixels behind you. And chunks stay loaded for a long distance around the player, deliberately, so that walking back does not stutter.
That is where the ratio comes from. Sixty one objects were visible. Everything else being drawn was correct to keep loaded and pointless to draw.
The fix is to keep the unit of loading as the chunk and make the unit of visibility the object. Those cannot be the same unit here, because a sect compound's buildings all belong to one chunk while the world is dozens of chunks across, so chunk level visibility would either draw the whole compound or none of it. A compound holds a dozen or so halls, such as Azure Cloud's pagoda, all owned by that one chunk.
The trigger you will forget
Visibility gets recomputed when the camera moves, which is the obvious trigger and the one everybody writes.
It also has to be recomputed when new chunks finish streaming in. Without that second trigger, anything that arrives while the player is standing still is never considered, so it is drawn forever regardless of where it is. Standing still is extremely common in an idle game. That trigger is doing more work than the obvious one.
Then the opposite problem
Building a chunk means scattering its props, and that work is synchronous. Measured, it is about seven milliseconds at the median, thirty six at the ninety fifth, and one hundred and forty two at its worst.
When you reveal a large area at once, the box being revealed can be twenty five chunks. Doing twenty five of those in a single frame is a freeze, and a freeze while the page is meant to stay responsive is exactly the thing I care most about avoiding.
So chunk assembly now runs against a per frame budget, nearest chunks first. Terrain loading is deliberately not budgeted, because ground appearing late is much worse than a tree appearing late. Population trails the ground by a frame or two and nobody notices. The land being streamed is laid out in this overview of the whole continent, if you want to see how far it goes.
The part I want to remember
I had two explanations for the roughness before I measured. One was about how the game hands work to the browser. The other was about a piece of the world I had recently changed and felt guilty about. Both were the kind of theory you can hold with real confidence, because both described mechanisms that genuinely exist and genuinely cost something.
Neither was the reason. The reason was a ratio nobody would guess, sitting in a system I considered finished, and it took a count of draw calls to find.
I now treat a performance hunch as a hypothesis with a required measurement attached, and I write the measurement down next to the fix. Not for discipline points. Because the next person to touch this code will be me in four months, holding a fresh confident theory, and the number in the comment is the only thing that will stop me.
More devlogs and the game: Myriad Immortal Sect, where you can roam the streamed world for free.




Top comments (0)