Guard pond accessors before attach; caught driving the live game
pondMass/pondCentroid/drainPondAt/dumpPond threw when this.water didn't exist yet — Lane A's HUD reads pondMass() every frame, including in the forecast/prep phases before the sail is rigged. Node tests always attach first so they never hit it; the live game did on the first frame. Guarded + a pre-attach assert so it can't regress. Verified in the assembled game: a flat quad ponds 780 kg (belly sagging below ground), dumps on break, and the merged browser selftest is 219/0/0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
b7f93d6486
commit
670443eea0
@ -582,6 +582,7 @@ export class SailRig {
|
||||
|
||||
/** Total water on the sail, kg. Lane A's "SAIL PONDING — get the broom" number. */
|
||||
pondMass() {
|
||||
if (!this.water) return 0; // the HUD may read this before the sail is rigged
|
||||
let m = 0;
|
||||
for (let n = 0; n < this.water.length; n++) m += this.water[n];
|
||||
return m;
|
||||
@ -593,6 +594,7 @@ export class SailRig {
|
||||
* @returns {{x:number,y:number,z:number,mass:number,node:number}|null}
|
||||
*/
|
||||
pondCentroid() {
|
||||
if (!this.water) return null;
|
||||
let m = 0, x = 0, y = 0, z = 0, node = -1, hw = 0;
|
||||
for (let n = 0; n < this.water.length; n++) {
|
||||
const q = this.water[n];
|
||||
|
||||
@ -879,6 +879,17 @@ test('ponding: the broom SAVES a flat rig that water would have killed', () => {
|
||||
return `kept 4/4 by sweeping the belly; unswept the same rig loses corners to water`;
|
||||
});
|
||||
|
||||
test('ponding: pond accessors are safe before the sail is rigged', () => {
|
||||
// Caught live: Lane A's HUD reads pondMass() every frame, including before the
|
||||
// player has rigged anything — and this.water doesn't exist until attach().
|
||||
const bare = new SailRig({ anchors: makeAnchors(HEIGHTS_FLAT) });
|
||||
assert(bare.pondMass() === 0, 'pondMass threw / was non-zero on an unrigged sail');
|
||||
assert(bare.pondCentroid() === null, 'pondCentroid should be null on an unrigged sail');
|
||||
assert(bare.drainPondAt(0, SIM_DT) === 0, 'drainPondAt should no-op on an unrigged sail');
|
||||
assert(bare.dumpPond() === 0, 'dumpPond should no-op on an unrigged sail');
|
||||
return 'pondMass/centroid/drain/dump all safe pre-attach';
|
||||
});
|
||||
|
||||
test('ponding: rain that the router swallows cannot silently pass', () => {
|
||||
// The integrator caught the wind router dropping the rain API this sprint,
|
||||
// which would have made every test above pass while ponding did nothing in the
|
||||
|
||||
Loading…
Reference in New Issue
Block a user