Hide the racket, and light the beam all the way to its edge
The mg racket is gone, not moved. It was a procedural racket drawn over a sprite that already holds one: straight up-court it projected onto the player's back as a floating oval, and offset to the side it just stuck out. The laser's far edge was pinned to the middle of the ad strip two commits ago and nothing appeared to change, twice. The geometry was always right -- each wedge layer faded to alpha 0 along its length, so the beam went invisible before it reached its own far corners and the VISIBLE end sat well short of the pinned one. The far stop is lit now, so the two are the same line. Verified by recomputing the projection: far corners at y 113.8, the ads' middle, against 110.2 unpinned. It also falls off with distance now, brightest at the strings and thinning down the court -- but never to zero, which is the trap above. Fixes a third instance of the empties-under-the-iterator bug: a rocket blast can bank the last kill of a game, and the duel or chapter boss that follows clears pellets[] mid-loop. shots, pellets, extras and the body loop all carry the guard. Also records that two consecutive render() calls do not produce the same frame -- render mutates camera smoothing as a side effect -- so frame-diffing to find where something was drawn measures the camera drift instead. It claimed the beam reached 16 px above where its own geometry could go. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6e88fd5bb9
commit
da9cca2f23
4 files changed
+48
-24
No files matched your search
+28
-1
@@ -385,10 +385,31 @@ them missed would hand out free ammo. The soak asserts `gunId` is never set with
|
||||
`mx || mz || assist`, and finger-steering zeroes `mx`/`mz` — so a player sliding left and right under
|
||||
auto-fire still counted as standing still and never ran. `mgMoving` is in that expression now.
|
||||
|
||||
**The oval on his back was the mg racket.** `drawMgRacket` put its head at `(P.x, 0.95, P.z - 1.35)`,
|
||||
**The mg racket is GONE.** It was a procedural racket drawn over a sprite that already holds one:
|
||||
straight up-court it projected onto the player's back as a floating oval, and offset to the side it
|
||||
just stuck out. Oliver: "can we please just hide it?" The pellets streaming up-court are the
|
||||
feedback. `drawMgRacket` is deleted, not commented out.
|
||||
|
||||
**(Previously) the oval on his back was the mg racket.** `drawMgRacket` put its head at `(P.x, 0.95, P.z - 1.35)`,
|
||||
which at this camera projects almost exactly onto the player sprite. Offset by `P.facing` it reads as
|
||||
a racket held out beside him.
|
||||
|
||||
**A third array had the empties-under-the-iterator bug.** A rocket blast can bank the last kill of a
|
||||
game, and the beat that follows (a duel, a chapter boss) does `pellets.length = 0` — so the pellet
|
||||
loop's next index read undefined and the frame threw. `shots`, `pellets`, `extras` and the body loop
|
||||
all carry the same `if (!x) continue` guard now. **Any array iterated in `updateZombies` that can
|
||||
contain something whose death advances the game needs it.**
|
||||
|
||||
**A gradient that ends at alpha 0 hides the thing you are aligning.** The laser's far corners were
|
||||
pinned correctly from the first attempt, but each wedge layer faded to fully transparent along its
|
||||
length — so the beam became invisible before it reached the pinned edge, the VISIBLE end sat well
|
||||
short of it, and moving the geometry appeared to do nothing twice in a row. The far stop is lit
|
||||
(0.62 of the layer's alpha) now, so the visible edge and the pinned edge are the same line.
|
||||
|
||||
**The beam falls off with distance** — brightest at the strings, thinning down the court, because
|
||||
that is what a beam travelling away from you does. The far stop is 0.32 of the layer's alpha: enough
|
||||
depth to read, never zero, so the visible end stays the pinned end.
|
||||
|
||||
**The laser's far edge is pinned in SCREEN space.** Running out to `beamLen` on the ground landed it
|
||||
on the ads' TOP line; it should die at their middle. `c3.y = c4.y = proj(0,0,-6).y - AD_H / 2` — the
|
||||
x's keep their perspective, the y is pinned. That holds in both orientations and leaves `beamLen`
|
||||
@@ -420,6 +441,12 @@ Drive the game deterministically via `window.T` with `javascript_tool`. The Brow
|
||||
context reports `document.visibilityState === 'hidden'`, so RAF is paused; halt it anyway with
|
||||
`window.requestAnimationFrame = () => 0` and step with `T.step(1/60)`. `T.press('Space')` = tap.
|
||||
Clear the intro first: `document.getElementById('intro')?.remove()`.
|
||||
- **Two consecutive `render()` calls do NOT produce the same frame**, so "draw it, change one thing,
|
||||
draw again, diff the pixels" silently measures nothing. `render()` mutates camera state as a side
|
||||
effect (`aimCam += ((G.aim ? 1 : 0) - aimCam) * 0.15`), so the whole scene shifts slightly between
|
||||
grabs and the diff lights up everywhere — it reported a laser beam extending 16 px above where its
|
||||
own geometry could possibly reach. To check WHERE something lands, recompute the projection
|
||||
directly (`T.proj(...)`) and compare numbers; keep pixel-diffing for "did anything at all change".
|
||||
- **The module-refresh list MUST include the VERSIONED entry point.** `index.html` loads
|
||||
`main.js?v=N`, and `fetch('main.js', {cache:'reload'})` does not bust that URL — so main.js alone
|
||||
stays stale through a reload while every other module is fresh. Read the src off the page:
|
||||
|
||||
Reference in new issue
Block a user