Fishing gauge native read - #13
Merged
Merged
Conversation
readWind matched two of the game's three arrow sprites. DartWind2 -- the one shown at 18 mph and up -- is red-orange, matched neither hue window, and so the strongest winds in the game read as 'none' and were modelled as still air. The same shape of bug as the magenta gate fixed in 2e4a0ab, and the last of them. Red is harder than the other two because it shares the HUD's own palette. The brown panel behind the arrow is hue 0-32 at saturation .30-.75; the amber text and trim beside it run hue 33-44. The arrow's own hue is quantised -- 73.5% of it under 36.3 and the rest exactly at 36.3, sitting inside the amber -- so hue cannot separate them at any cutoff. Brightness looked like the answer and was not. The arrow is v=1.00 throughout and the brown never passes .72, but the amber reaches .96. A first cut at .85 invented a wind on 70 frames of a recording that has none; .97 still let 22 through. That was fitting a constant to whichever frame had last been looked at, which is the same mistake this file already carries a warning about in the aim reach floor. What actually separates an arrow from HUD text is that an arrow is a solid blob. The sprites fill 4-8% of the scanned window (480, 518 and 258 px of a window 0.12W x 0.10H); the amber scatter being picked up was 22-32 px, under half a percent. The old "at least 8 pixels" test dates from when only cyan and magenta were matched, neither of which appears in the HUD at all. It is now 2% of the window area, which sits in a 15x gap and is resolution independent. Replayed against three recordings, all of which report no wind: 1032, 2369 and 3043 frames, zero false reds, and aim counts unchanged at 1032, 2369 and 2983. Those recordings can only prove red is not seen where it should not be. None of them contains an 18+ mph wind, so that red IS seen when it should be remains unverified until one turns up in play. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Expanding the clicker pushed a collapsed Darts panel most of a screen down, past the empty space under the Suite panel where it plainly belonged. That is what shelving does: every wrapped panel starts below the TALLEST one before it, so one tall panel sets the depth for everything that follows and leaves a hole beside the short ones. Panels now run along the dock's edge until the viewport is used up, which fixes a set of lanes -- columns for a top dock, rows for a left one -- and everything after goes into whichever lane is currently shallowest. A short panel fills the gap beside a short neighbour rather than clearing the tall one. Lanes are disjoint along the edge, so nothing can overlap however the depths fall, and a panel is placed in the shallowest lane it actually FITS in where one exists, since the panels differ in width by about 30px and one dropped into a narrower lane would hang over its neighbour. The rebuilt suite also carries the darts wind change from 1a18ba3. Note for anyone editing the suite parts: `node --check` on 00-head.js or any other 0*-*.js will always fail. They are fragments -- 00-head opens the IIFE and 05-hub closes it -- so a syntax error there means nothing. Check the built idleon-suite.user.js instead. Reading that failure as real cost a revert of a good edit today. Not seen running; the packing postdates the last injection. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The helper marked where each fish is and what power lands on it, but said
nothing about how close is close enough. That is knowable exactly. The game's
test is
|fishX - bobberX| < 6 + SIZE[type]
with SIZE = [6,6,9,10,12,13,17,17] in lane units, the 6 being the bobber's own
half-width. Points identify the type -- 1pt is type 2, 2pt type 3, 3pt type 4,
5pt type 6 -- so the tolerances are 15, 16, 18 and 23 lane units, and the
pufferfish (type 5, size 13) is 19.
Those are stored as fractions of the lane rather than pixels, because the lane
is about 299.5 lane units across. Two independent routes agree on that number:
inverting the measured aim curve puts the lane's ends at game x 11 and 311, and
the game seeds fish between 40 and 295 with the bobber landing between 24 and
285, all inside that span. A fraction survives any window size; a pixel count
would not.
Two things are drawn from it. On the lane, a bar as wide as the real tolerance,
so a near miss looks near instead of mysterious -- a whale is half again as
forgiving as a fish, which the sprites do not suggest. On the gauge, the tick
becomes a BAND: the ends of the catch window mapped back through the aim curve
are the range of gauge fills that still land the cast. That is the release
slack, which is the thing actually being aimed at; a tick says where perfect is
and nothing about the room around it. The curve is not linear, so the band sits
asymmetrically around the tick and tightens for fish further out.
The pufferfish gets the same bar, since its window is how far away to stay, and
at 19 units it is wider than every catch except the whale.
Replayed over a fishing recording: 1289 frames, 1267 with a lane, no exceptions
-- which matters because the standalone has no error containment around its
loop, so a throw in the drawing would stop the helper dead. The bars and bands
have NOT been seen rendered; that needs a live fishing spot.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The oscillator correction was disabled in 57faab9 because recovering cos from |sin| plus a direction-of-travel sign is discontinuous exactly where the platform spends most of its visible time. On a real run it flipped sign 34 times and jumped by more than 0.5 in cos 17 times, worst case +0.946 to -0.955 across a single frame, so the preview leapt between the strongest and weakest shot. Nothing needs guessing, because the period is known exactly: G16[0] gains 1.3 every 20ms and phi = 1.1*G16[0] degrees, which is 71.5 deg/s and a 5.035s period. With w fixed, platY(t) = y0 + A*sin(wt) + B*cos(wt) is ordinary linear least squares in three unknowns over a rolling window, and cos(phi) = (A*cos(wt) - B*sin(wt)) / hypot(A,B) comes straight out -- continuous everywhere, with no sign to choose and nothing to flip at a turning point. The window is just over half a period. Shorter and sin and cos are too alike across it to separate, which lets A and B trade places freely. The fit is rejected unless its amplitude lands near the real swing (110 of 540 on the design canvas) and its residual is small against that amplitude, because a fit that has latched onto drift instead of the oscillation gives a confident wrong phase, which is worse than no correction. Replayed against the recording of the run that regressed: before after sign flips 34 7 (genuine zero crossings; cos passes jumps > 0.5 17 0 through zero twice a cycle) largest jump 1.90 0.119 cos range -0.99 .. 1.00 STILL DISABLED at the call site. Fixing the estimator is not the same as showing the correction helps, and the test for that -- whether each shot's fitted R tracks the cos it was thrown on -- cannot be run here: neither hoops recording commits a single per-flight fit, since commitCal wants 6+ tracked frames per flight and the replay does not produce them. cosPhi and the per-flight fit are both still published on the probe, so a live run would settle it. Re-enabling is one argument at the shotCurve call. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…enable
The physics was never in doubt: platform height and release velocity are one
oscillator in quadrature, so whether the platform is rising or falling changes
where the shot lands from the same height. What was wrong was the geometry for
how that redistributes across the arc, and it was wrong confidently.
Re-cutting the parabola from a fixed release point predicted the effect landing
almost entirely on R, the far crossing, and barely touching L. Driven against
the offline rip of the game -- 65 shots, 14 committed per-flight fits, cos
sampled across its full range -- it is the other way round:
A vs cos +0.0235 +-0.0435 r2 0.02 predicted 0
L vs cos -0.0949 +-0.0165 r2 0.73 predicted -0.0171
R vs cos +0.0253 +-0.0132 r2 0.23 predicted -0.0654
Curvature ignores the oscillator exactly as the physics says, which is the part
of the model that holds -- g/2vx^2 sees neither. But the coupling lands in L at
5.8 standard errors while R has the wrong sign and does not clear two. Most
likely because the tracked part of a flight pins the descending branch, leaving
L to absorb the change: R is measured, L is extrapolated.
So the slopes now come from the fits. R's stays in at its measured value
despite being weak, since dropping it would tilt the arc and 0.0253 is small
enough that being wrong about it costs little.
Re-enabled at the call site. It was switched off in 57faab9 because the old
estimator made the preview jump at every turning point; measured again now with
the phase fit and the correction live, over 12s of play: cos spans the full
-1..1, six sign changes where a 5.035s period predicts about five real zero
crossings, no jump over 0.5, largest 0.150. The old estimator managed 17 jumps
over 0.5 and a worst of 1.90.
None of this could be measured before. Neither hoops recording commits a single
per-flight fit -- commitCal wants 6+ tracked frames per flight and the replays
do not produce them -- so the offline rip is what made the test possible at all,
and it gives better data than live play could: unlimited shots, no cooldown,
and cos swept across its whole range by shooting slightly off the period.
Still not outcome-validated. That the predicted arc now matches the measured
coupling does not prove it sinks more shots, and the honest test for that is
whether ghostMade tracks made over a long run.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…shotA Re-enabling this in 10998a2 rested on the per-flight fits correlating with cos. That is the helper's own reading of its own arc, and it is a much weaker test than whether shots go in. Measured properly against the offline rip, using the game's own score as ground truth and pairing each release to its result: GREEN n=28 1/28 swish 19/28 scored (68%) red n=21 0/21 swish 14/21 scored (67%) Green means "this arc threads the hole". One of 28 did. And green scores no better than red, so the preview carries no information about whether the shot goes in. A second-order correction cannot be judged against a prediction that is not discriminating at all. Play matches. Descending shots come out worse than ascending (10/16 against 9/12, which is ~0.7 SE and proves nothing alone, but is the reported direction) and ascending is off too when the rim is CLOSE -- small u, where the arc is dominated by uL, which is exactly the term this correction moves hardest, up to 0.095 of canvas width. The measured L slope looks too large to apply raw. Nothing measured here is thrown away: platCos and its phase fit stay, and so do the coupling numbers. The physics is still right. But this cannot ship while the arc's height at the rim is off by a mean of 54.7px, worst 117.5px, against a hole far narrower than that -- a 70px correction is not measurable on top of a 55px baseline error, which is also why 1 in 28 is the swish rate. shotA goes back to 2.233 as well. v7 replaced that fitted value with 2.177, derived as g/2vx^2 on the 960-wide design canvas, arguing the 2.6% gap was a tracking bias rather than noise. The offline rip's own per-flight fits put curvature at 2.2205, with the original fit and not with the derivation. Two independent measurements agreeing against one derivation means the derivation was wrong -- the same way the L/R geometry was. The next thing worth measuring is the SIGNED error at the rim: the ball's actual height as it crosses, against the predicted arc's height there, over a few hundred automated shots. That gives direction and magnitude instead of "missed", which is what fixing the base arc needs. The offline rip makes it free. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…r signed
"Missed" is not a measurement. The number that decides a hoops shot is the
height of the arc where it passes the rim, so the helper now publishes exactly
that -- ghostRimY -- which turns the error into something with a direction and
a size instead of a verdict.
Measured against the offline rip, using the game's own state for both sides:
its ball position [91][92] and hoop position [95][96], sampled in-page each
frame, against the helper's own predicted arc at the same x. No pixel inference
anywhere, on either side.
SIGNED rim error, n=15 (negative = ball passes ABOVE the prediction)
mean -76.3px median -91.5px sd 66.2 range -161.9 .. +49.6
ascending -93.1px (n=12)
descending -9.2px (n=3)
The ball flies well above the predicted arc, and nearly all of it is on
ascending shots; descending ones sit close to the prediction. That is what the
game's constants predict if the oscillator is ignored: ascending is cos<0, and
vy = -2.9 + 0.7*cos makes that the STRONGER shot at -3.6 against -2.2, so a
prediction built on an average-strength shot is undershot vertically by exactly
the sort of margin seen here.
So the coupling disabled in 5f0193a is real and is needed; what was wrong was
its form. Applying it through uL moved the arc in a way that did not correct
the height at the rim -- which is consistent with the earlier finding that
ascending and descending had the SAME error at the rim while the correction was
active, and with the report that close-rim shots were off.
A first pass at this measurement gave mean +32 against a median of -22, which
is a distribution dragged by one +346px outlier: the ball resets to the
player's hands between shots, crossing the hoop's x travelling LEFT. Requiring
a rightward crossing during flight fixed it and the two statistics now agree in
sign. Worth remembering that a mean and median of opposite signs means the
summary is being set by outliers, not by the effect.
n=15 with only 3 descending is thin. The rig is cheap to re-run now, and the
next step is enough shots to fit the correction against the rim error directly
rather than against the per-flight fits.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.