2026-09-16 · KURO KISHI

Hit feedback that doesn't hide the fight

Void Engine's last environments and bosses are in, and the rest of the day went to making it readable and steady. Opaque white hit flashes became soft pulses, a late boss arrival made animations strobe, and the frame-rate controller turned out never to have been called.

Void Engine, the 3D rebuild of Kuro Kishi, has all eight stages now. Most of today was spent on how the game reads and how steadily it runs.

Hit feedback

Enemies used to flash opaque white when hit. In a dense fight that covers the thing you are trying to read. They now take two soft, translucent pulses laid over the original armour. The overlay materials and geometry are shared, and the effect cannot produce shatter debris. Boss armour breaks, phase changes, boss deaths and capital deaths no longer add a full-screen flash, and contact glows are smaller and dimmer. Damage to the player keeps its own, distinct feedback so it never gets lost among the rest.

Screen Shake and Screen Flashes are saved settings that work independently of the enemy pulses. Turning either off clears any shake or flash already in progress.

Two bugs that only show up late

A boss that crashed on death

Shattering an armoured boss read a bounding box that had never been computed for geometry that was never rendered, and threw. The full-campaign run found it. Shattering now computes missing bounds first and ignores hidden and effect meshes. There is a regression for unrendered geometry.

Animations that strobed when a boss arrived late

Some background effects change speed when a boss shows up. The phase was computed as the new speed multiplied by total elapsed time. If the boss arrived late, that multiplication jumped the phase by a large amount in a single frame, and the effect strobed. Phases now accumulate the current speed each frame, so a change in speed changes the rate and nothing else. A related one: pausing could silence a charge shot that was already being held. Resuming now restarts the held-charge audio without resetting how much charge you have built.

Making it steady

Several of these were wired up and never connected.

  • The automatic resolution controller existed and was never called from the main loop. It now reads real frame timing. Sustained drops below 55 FPS cost a gentle 6% of resolution, severe drops 12%, and recovery waits for stable fast frames.
  • Bloom resized its settings but not its actual render targets. It now resizes the targets.
  • Hidden tabs no longer render, and paused scenes are no longer redrawn every frame. A resize still redraws a paused one.
  • The HUD updates at 15 Hz and only while the game is visible, keeps references to its nodes, and writes text only when it changes. The boss bar no longer rebuilds its DOM every frame.
  • Projection vectors and projectile colours are reused instead of allocated each frame.

Disposing a stage now releases materials and textures as well as geometry. Three repeated cycles through the last three stages held steady at 153 textures and 1,871 geometries.

Audio and comfort settings used to recreate render targets and reset the resolution controller whenever one changed. They no longer do, and focus stays on the setting you are changing. Pause now has an Options screen that returns to the same paused run.

Measured

Local opening-gameplay measurements, High, 1280 by 720, pixel ratio 1. They are short samples and do not cover every encounter or any physical device.

stagemean frame95th percentile
616.71 ms17.2 ms
716.67 ms16.9 ms
816.71 ms17.2 ms

A heavier test hits a late boss repeatedly. An earlier sample ran 18.46 ms mean with a 27.8 ms 95th percentile. After the controller changes it ran 17.41 ms mean and 26.3 ms 95th, about 57 FPS, with the adaptive pixel ratio settling at 0.789. The controller trades some internal resolution for steadier frames. Gameplay is randomised, so that is not a clean A/B.

Background action that reacts to the fight

Boss arrivals now change the backdrop. Each stage has its own reaction, drawn on one reusable shader plane that fades with the stage mood and sits behind the actors. Spawning a boss directly now triggers the same mood change as the normal warning sequence, which it had skipped.

In the city, the destruction scenes are larger and nearer, with twin lasers and timing adjusted so a robot and its target are on screen together. Collapsed sections stay ruined until their scene wraps offscreen, and the debris is instanced from fixed geometry.

Submarines that sink

The two submarine capitals in the underwater stage have no exposed-core fight. When the last gun dies, they are destroyed: explosion bursts, an accelerating fall through the floor, and the wreck stays visible until it leaves the screen. A sinking hull stops shooting, stops colliding and stops absorbing shots. Score, kill credit and two capsules are awarded once, at the point of destruction, before the hull falls out of reach. A duplicate-hit guard keeps them from being paid twice.

The full eight-stage run passes with no failures and no browser errors.