diff --git a/tools/site_audit/garden_probe.html b/tools/site_audit/garden_probe.html index 38c97ac..1f8590c 100644 --- a/tools/site_audit/garden_probe.html +++ b/tools/site_audit/garden_probe.html @@ -8,10 +8,10 @@ gardenHailExposure, stepped exactly the way main.js:931-941 steps it) for a set of rig lines, and prints predicted garden HP beside the audit's cover%. - It is a PROBE, not the fix: the garden drain weights are private to main.js, so - the constants below are a temporary copy, marked and asked-about in THREADS. - The moment A exports the garden model this page imports it and the copy dies. - Nothing ships against a duplicated constant — that is how this repo gets bitten. + SPRINT13: the garden model is A's js/garden.js now (the export this page's + first version asked for), so the probe flies the SAME createGarden main.js + flies — the temporary constant copy died the day the export landed, per the + fake → ask → landed → delete-the-fake protocol. Browser-only by necessity: skyfx needs `document` (verified — node throws "document is not defined"), so garden prediction can never live in audit.mjs. @@ -48,13 +48,9 @@ import { createWind } from '../../web/world/js/weather.js'; import { createSkyFx } from '../../web/world/js/skyfx.js'; import { SailRig } from '../../web/world/js/sail.js'; import { HARDWARE, FIXED_DT } from '../../web/world/js/contracts.js'; +import { createGarden } from '../../web/world/js/garden.js'; import { AUDIT, auditSweep } from './sweep.js'; -// ⚠️ TEMPORARY COPY — main.js's garden model is module-private (HAIL_WEIGHT, -// RAIN_WEIGHT, GARDEN_DRAIN, createGarden). Asked A to export it in THREADS; -// this dies the moment it lands. Do not let this page outlive the ask. -const HAIL_WEIGHT = 5.0, RAIN_WEIGHT = 0.25, GARDEN_DRAIN = 0.9; - const q = new URLSearchParams(location.search); const siteName = q.get('site') || 'site_02_corner_block'; const stormName = q.get('storm') || 'storm_03b_earlybuster'; @@ -102,26 +98,19 @@ async function run() { .attach(ids, Array(4).fill(hwTier), 1.0); } const sky = createSkyFx({ wind, night: true }); - let hp = 100, byHail = 0, byRain = 0; + // THE model, not a copy: main.js's own createGarden, imported from garden.js. + const garden = createGarden({ setPlants() {} }); const n = Math.round(stormDef.duration / FIXED_DT); for (let i = 0; i < n; i++) { const t = i * FIXED_DT; if (rig) rig.step(FIXED_DT, wind, t); sky.step(FIXED_DT, t, { sail: rig }); - const rainExp = sky.gardenExposure(bed, t); - const hailExp = sky.gardenHailExposure(bed, t); - const dHail = HAIL_WEIGHT * hailExp * GARDEN_DRAIN * FIXED_DT; - const dRain = RAIN_WEIGHT * rainExp * GARDEN_DRAIN * FIXED_DT; - const total = Math.min(hp, dHail + dRain); - if (total > 0) { - const fh = dHail / (dHail + dRain); - byHail += total * fh; byRain += total * (1 - fh); - hp -= total; - } + garden.step(FIXED_DT, sky.gardenHailExposure(bed, t), sky.gardenExposure(bed, t)); } const cornersLost = rig ? rig.corners.filter((c) => c.failed).length : 4; - return { hp: +hp.toFixed(1), byHail: +byHail.toFixed(1), byRain: +byRain.toFixed(1), cornersLost }; + return { hp: +garden.hp.toFixed(1), state: garden.state, + byHail: +garden.damage.hail.toFixed(1), byRain: +garden.damage.rain.toFixed(1), cornersLost }; } el('sub').textContent = diff --git a/web/world/js/tests/balance.test.js b/web/world/js/tests/balance.test.js index 1ac9c2d..5342a71 100644 --- a/web/world/js/tests/balance.test.js +++ b/web/world/js/tests/balance.test.js @@ -28,6 +28,11 @@ import { SailRig } from '../sail.js'; import { createSkyFx } from '../skyfx.js'; import { createWind, loadStorm } from '../weather.js'; import { HARDWARE, FIXED_DT, START_BUDGET } from '../contracts.js'; +// SPRINT13: the garden weights come from garden.js — the SAME module main.js +// flies — not from a local copy. The old `const GARDEN_DRAIN = 0.9 // main.js` +// here was the drift A's export exists to kill: a retune would have landed in +// the game and left this suite green against last sprint's numbers. +import { GARDEN_DRAIN, HAIL_WEIGHT as W_HAIL, RAIN_WEIGHT as W_RAIN } from '../garden.js'; const [CARABINER, SHACKLE, RATED] = HARDWARE; @@ -35,9 +40,6 @@ const [CARABINER, SHACKLE, RATED] = HARDWARE; const WIN = (hp, lost) => hp >= 50 && lost < 2; /** main.js's CALM_STORM — what wind.use() hands the rig outside a storm, and so what settles it. */ const CALM_STORM = 'storm_01_gentle'; -const GARDEN_DRAIN = 0.9; // main.js -const W_HAIL = 5.0; // main.js, decision 13 — integration weights -const W_RAIN = 0.25; /** * The yard is READ FROM world.js, never copied.