One WebGL context, three leaks
Everything on this site draws in a single WebGL context. Then a piece arrived that brings its own geometry: a galloping horse in 17,022 vertices. Sharing the context with it went wrong in three ways, and fixing them turned up an engine bug that had been there from the start.
The engine owns the loop, the clock, the pointer and the theme. A custom piece writes two functions, draw and dispose, and borrows the rest. That contract was the easy part.
The three leaks
State. The horse turns depth testing on, and whichever shader ran next inherited it. The engine now puts every fixed-function setting back to its base before each frame, whoever drew last.
Vertex arrays. The shared triangle that every other piece draws on has to bind its own array and let it go afterwards, or it picks up the horse's.
Context loss. When the context dies, the horse's buffers die with it. Disposing them again was an error, so a custom scene is no longer disposed on loss.
The old bug
Pointer energy only fell when the pointer left the stage. A pointer resting on it kept every scene at full power forever, and nobody had rested a pointer on a scene long enough to notice.
The cost of the horse: 70 ms of setup, no growth in first-load JavaScript, and no long tasks while moving between pieces.