From 18effa6e7870f8bf519204f70a429f03cd30ced3 Mon Sep 17 00:00:00 2001
From: pkuzic
Date: Sat, 26 Sep 2026 02:34:58 +0100
Subject: [PATCH] MONKEY (perf): bleed fixtures bucket sources per placement
and run at 10 Hz
update_bleed_fixtures walked every interior source in the world four times per
doorway every frame (~1.0 ms/frame main thread, traced, Northshire at High).
Sources are now bucketed per placement once (same rows, same order, same sums:
another placement's claimant weighs 0), the evaluation runs at 10 Hz with
arrivals and dial changes bypassing the cadence, and the light is written only
on a real change. Captures inn-noon and perf-abbey-night are pixel-identical.
Co-Authored-By: Claude Opus 5.5
---
crates/benilla-world/src/lighting/daylight.rs | 54 ++++++++++++++++---
1 file changed, 48 insertions(+), 6 deletions(-)
diff --git a/crates/benilla-world/src/lighting/daylight.rs b/crates/benilla-world/src/lighting/daylight.rs
index 7738445c..60387289 100644
--- a/crates/benilla-world/src/lighting/daylight.rs
+++ b/crates/benilla-world/src/lighting/daylight.rs
@@ -1811,9 +1811,14 @@ impl BleedSeed {
}
}
+/// MONKEY (perf): seconds between two bleed evaluations (see [`update_bleed_fixtures`]).
+const BLEED_EVAL_PERIOD: f64 = 0.1;
+
/// One interior-lane source as the bleed evaluation needs it — the packer's own arithmetic, minus
/// the flicker (a bleed must not breathe with the hearth it carries: the pool it feeds is a whole
/// doorway, and a wobbling doorway is a wobbling building).
+// MONKEY (perf): Copy, so the per-placement buckets in `update_bleed_fixtures` can hold rows.
+#[derive(Clone, Copy)]
struct BleedSource<'a> {
pos: Vec3,
/// Committed colour, NORMALISED like the shader's `c_norm`.
@@ -1981,7 +1986,22 @@ pub fn update_bleed_fixtures(
>,
time: Res