diff --git a/HANDOFF.md b/HANDOFF.md
index 910f5de..ca2d718 100644
--- a/HANDOFF.md
+++ b/HANDOFF.md
@@ -443,6 +443,9 @@ that holds that height all the way out instead of sloping to the ground — that
makes the rest possible. Sloping, it lay flat on the grass across the whole far half, so there was
nothing for it to cut exactly where the crowd stands.
+- **`beamLen` is the DRAWN length now, not just the kill range.** It used to be solved every frame so
+ the far end landed on the middle of the ad strip, which made it a knob that visibly did nothing.
+ One meaning beats one clever behaviour.
- **`TUNE.beamBand` is a live A/B between two looks**, flippable from the T panel on the phone.
**1 (default) = the BAND**: drawn the way the ball's aim trajectory is drawn — a path down the lane
whose width comes from each point's OWN projection scale, so it narrows into the distance like
@@ -494,6 +497,27 @@ nothing for it to cut exactly where the crowd stands.
are AIMING rather than only on the shot. Measured on desktop: 0.27 ms/frame with 20 bodies against
a 16.7 ms budget.
+## T.laserScene() — the tuning playground
+
+`T.laserScene()` in the console (or `#laser` on the URL) poses six bodies of different types at known
+depths with the laser armed and a pull held. `T.laserFire()` shoots it; `T.laserScene()` re-poses.
+
+**It does NOT pause, and that is the point.** The first version froze the world so the picture would
+hold still — and then every value changed in the T panel did nothing visible, because nothing
+redrew. Oliver: "tuning the parameters does not change the view (because it's paused?)". The bodies
+are held still individually (`v = 0`) and spawning is off instead, so the picture is stable while the
+render loop keeps running. **Never pose a tuning scene by halting rAF or pausing** — a still frame
+you cannot change is worth nothing.
+
+**A boolean living in TUNE must be tested with `>= 0.5`.** The panel renders every TUNE key as a
+number input stepping by 0.02, so one nudge on `beamBand` set it to 0.02 — still truthy — and the
+renderer silently switched variants under him mid-tune.
+
+The laser's shape was tuned this way and these are Oliver's numbers: `beamY` 0.95, `beamLen` 23,
+`beamW0` 0.08, `beamW1` 3.1, `beamOriginLift` 0.44, `beamBorder` 0.18.
+**`beamY` and `beamLen` interact** — a lower plane meets the ad strip at a shorter distance, so
+dropping one wants the other shortened.
+
## T.pause(true) — freeze the world, keep drawing
`T.pause(true)` stops `update()` but keeps `render()` running, so a value changed in devtools shows
diff --git a/config.js b/config.js
index 886d8a9..7c35238 100644
--- a/config.js
+++ b/config.js
@@ -240,27 +240,36 @@ export const TUNE = {
testSpawnEvery: 0.9,// s between spawns: they keep coming
testLevel: 20, // the roster level pickVariant pretends to be at, so every body type can turn up
// ---- THE LASER's wedge: aim and release like a serve, and a plane of light widens down the lane
- beamLen: 34, // m it reaches. Was 26, which stopped at the far baseline and read as the beam
- // being CUT OFF in mid-court; the player stands at z~24, so this carries it past
- // the baseline and up into the courtside ads, which is where light should stop.
- beamY: 1.15, // m — the height the plane HOLDS down the court, and the line it cuts bodies at.
+ beamLen: 23, // m it reaches — the DRAWN length as well as the kill length. It used to be only
+ // the kill: the drawn length was solved each frame so the far end landed on the
+ // middle of the ad strip, which meant turning this knob did nothing you could
+ // see. One meaning now. Tuned WITH beamY: a lower plane reaches the ads sooner,
+ // so dropping one wants the other shortened. Oliver's numbers, 2026-08-03.
+ beamY: 0.95, // m — the height the plane HOLDS down the court, and the line it cuts bodies at.
// It used to slope to the ground by about 20 m out, which meant that across the
// whole far half it lay flat on the grass: nothing to cut, and the split would
// have been invisible exactly where the crowd stands. Chest on a shambler, belly
// on a brute, thigh on the roller man — so a bigger body visibly takes it lower.
- beamOriginY: 1.25,// m — it leaves the PLAYER at chest height, not the racket head. Emitted from
- // the racket (2.2 m) the apex hung in the air above him and read as detached;
- // out of his chest, level with the plane it becomes, it reads as HIS shot.
+ beamOriginLift: 0.44, // m the apex sits ABOVE beamY. It is a lift, not an absolute height, so
+ // lowering beamY brings the near end down with it — set as an absolute, dropping
+ // the plane left the apex hanging at chest height with the beam sloping away
+ // beneath it. It leaves the PLAYER, not the racket head: emitted from the racket
+ // (2.2 m) the apex floated above him and read as detached.
beamRise: 0.14, // fraction of the length it takes to settle from the origin to that height
- beamW0: 0.06, // m half-width at the racket — a POINT. At 0.35 it left the racket as a 0.7 m
- // bar hanging in the air rather than as something emitted from the strings.
- beamW1: 5.0, // ...and at the far end. It is a CONE: the spread is the point of it
+ beamW0: 0.08, // m half-width at the racket — very nearly a point
+ beamW1: 3.1, // ...and at the far end. It IS a cone — but a gentle one. At 5.0 the world width
+ // grew so much faster than the projection shrank that on screen it opened out
+ // while the court receded, and the eye read that as a flat shape stuck to the
+ // glass. Growing slowly, the two roughly cancel and it lies in the world.
// A/B, live from the T panel on the phone. 1 = draw the laser the way the BALL's aim band is
// drawn: a path down the lane whose width comes from each point's OWN projection scale, so it
// tapers into the distance and sits in the world. 0 = the solid widening cone.
// The cone is a real projection, but it GROWS in world width (0.06 m -> beamW1), so on screen it
// opens out while everything else recedes — which is what reads as a flat sticker.
- beamBand: 1,
+ beamBorder: 0.18, // px of the two outer edge lines — a hairline. At 1 they were the heaviest
+ // thing on the court and boxed the cone in.
+ beamBand: 0, // 0 now: the CONE won, once it stopped ballooning (see beamW1). >= 0.5 is ON —
+ // the panel steps by 0.02 and a nudge to 0.02 used to flip the renderer silently
beamBandW: 0.30, // world half-width of that band — CONSTANT, which is what makes it taper
beamT: 0.42, // s the wedge stays drawn
dmgBeam: 8, // what it takes off a BOSS. An ordinary body is not damaged by the beam, it is
diff --git a/index.html b/index.html
index 1c19703..d1cecdb 100644
--- a/index.html
+++ b/index.html
@@ -179,6 +179,6 @@
-
+