#131 false lock FIXED: miss-means-miss -- the pick answers only for drawn geometry
Night-12 field report (Ronin/Conn Man/Oracle, blackhawk-correlated): lock ring lit with the reticle visibly off the mech + no-reg complaints. Root cause: TWO port stand-ins answered where the 1995 card (which cast against the DRAWN geometry) would miss -- the pick's any-object sphere fallback and the caller's whole-mech AABB fallback. The regime that exposes them: a LEVEL boresight over a SHORT mech -- the blackhawk's mesh tops out below eye-ray height, so the ray clears every triangle but pierces the fat cull spheres; the ring lights with the reticle above the mech's head (the operator watched exactly this on the sweep bench). Careful aimed-down fire rides triangles, which is why Oracle's per-panel audit passed on the same build. Fix: MechSegmentPick returns 1=drawn-geometry hit / 0=TRUE MISS / -1=no render tree; the sphere may answer ONLY for a mesh the reader cannot parse (pm==0 -- currently none exist: counters objs/invFail/noTri all clean); the AABB survives ONLY as the pre-tree replicant grace. A readable mesh the ray misses is a MISS -- no lock. Verified (2-node vs bhk1 at 100u, all runs on force-relinked string- verified exes after today's stale-link flake): - LEVEL lock-sweep: 0 locks all run (pre-fix: lock band from 168 sphere answers; picksrc tri=0 sphereFB=168). - DOWN-PITCHED sweep: locks return 100%% tri-sourced (tri=158 sphereFB=0), landing on real parts (rarm/ldleg/rdleg) with honest gaps. - Full zone-walk matrix: tri=18874 sphereFB=0 box=0; victim took 156 hits across 16 zones incl. both side torsos -- combat un-regressed. New instruments (all env-gated): BT_LOCK_SWEEP=<axis> torso pan (the operator-visible lock-envelope bench), [locksweep] transition log, BT_LOCK_ENVELOPE synthetic unit-sweep probe, [picksrc]/[pickbox] source telemetry with objs/invFail/noTri localization counters. Bench: scratchpad/night12/zonewalk_bhk.sh. NOTE for the field: locking is now strictly TIGHTER (ring = reticle truly on the machine). If era testers feel the pods were more forgiving, Draco's "slight lock linger" memory becomes a deliberate investigation (sourced hysteresis), not an accidental sphere halo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
f279e38707
commit
546aabd5ba
@@ -1688,7 +1688,8 @@ int
|
||||
{
|
||||
std::map<Entity*, MechRenderTree>::iterator it = mMechRenderTrees.find(mech);
|
||||
if (it == mMechRenderTrees.end() || it->second.wrecked)
|
||||
return 0;
|
||||
return -1; // #131: NO TREE (unbuilt replicant / wreck) -- the caller may
|
||||
// box-test; distinct from 0 = a true drawn-geometry MISS.
|
||||
|
||||
// Selection is SPECIFICITY-FIRST: among the spheres the ray pierces, the
|
||||
// SMALLEST radius wins (normalized-distance tie-break). Neither nearest-
|
||||
@@ -1713,6 +1714,7 @@ int
|
||||
int triHit = 0;
|
||||
d3d_OBJECT *triBestObj = 0; // #124-PATCH: winning object + tri
|
||||
size_t triBestK = 0; // (triangle ordinal in its IB)
|
||||
int dbgTriObjs = 0, dbgInvFail = 0, dbgNoTri = 0; // #131 telemetry
|
||||
|
||||
// #124 CORRECTED (2026-08-04, field pushback vindicated): the pick's zone
|
||||
// is the struck PATCH's authored dz_* tag, with the segment's SKL dzone as
|
||||
@@ -1769,12 +1771,17 @@ int
|
||||
<< " ib=" << (void *)obj->mBgfIB
|
||||
<< " stride=" << obj->mBgfStride << ")\n" << std::flush;
|
||||
}
|
||||
if (pm == 0)
|
||||
++dbgNoTri;
|
||||
if (pm != 0)
|
||||
{
|
||||
++dbgTriObjs;
|
||||
// ray into object-local space (affine inverse; segment poses are
|
||||
// rigid, so local t == world t after direction normalization is
|
||||
// preserved by construction below)
|
||||
D3DXMATRIX w2l;
|
||||
if (D3DXMatrixInverse(&w2l, 0, &l2w) == 0)
|
||||
++dbgInvFail;
|
||||
if (D3DXMatrixInverse(&w2l, 0, &l2w) != 0)
|
||||
{
|
||||
D3DXVECTOR3 lo, ld;
|
||||
@@ -1815,7 +1822,15 @@ int
|
||||
}
|
||||
}
|
||||
|
||||
// ---- sphere FALLBACK bookkeeping (unchanged selection) ----
|
||||
// ---- sphere FALLBACK bookkeeping -- #131 MISS-MEANS-MISS: only an
|
||||
// object whose drawn mesh is UNREADABLE (pm == 0) may answer by
|
||||
// sphere. A readable mesh the ray misses is a MISS. The old
|
||||
// any-object sphere halo produced lock-without-mech: level rays over
|
||||
// the squat blackhawk read tri=0 / sphereFB=168 on the sweep bench,
|
||||
// and the operator watched the reticle pass over its head with the
|
||||
// ring lit. The 1995 card cast against the DRAWN geometry -- no halo.
|
||||
if (pm != 0)
|
||||
continue;
|
||||
float score = d2 / r2; // 0 = dead-center thread
|
||||
if (r > bestR
|
||||
|| (r == bestR && score >= bestScore))
|
||||
@@ -1828,6 +1843,27 @@ int
|
||||
hitAny = 1;
|
||||
}
|
||||
|
||||
// #131 telemetry: how did this pick answer? (TRI = drawn-geometry hit,
|
||||
// the authentic semantic; SPHERE = the fallback answered with no triangle
|
||||
// struck -- the false-lock candidate.) Throttled under BT_PICK_LOG.
|
||||
// objs/inv/noTri localize a dead triangle pass: objs = sphere-nominated
|
||||
// objects entering the tri test, inv = SILENT skips from a failed
|
||||
// world-matrix inverse (degenerate l2w), noTri = pick-mesh read failures.
|
||||
if (getenv("BT_PICK_LOG"))
|
||||
{
|
||||
static int s_src[3] = {0,0,0}; // [0]=tri [1]=sphere [2]=miss
|
||||
static int s_objs = 0, s_inv = 0, s_noTri = 0;
|
||||
static int s_rep = 0;
|
||||
s_objs += dbgTriObjs; s_inv += dbgInvFail; s_noTri += dbgNoTri;
|
||||
++s_src[triHit ? 0 : (hitAny ? 1 : 2)];
|
||||
if ((++s_rep % 240) == 0)
|
||||
DEBUG_STREAM << "[picksrc] tri=" << s_src[0]
|
||||
<< " sphereFB=" << s_src[1] << " miss=" << s_src[2]
|
||||
<< " objs=" << s_objs << " invFail=" << s_inv
|
||||
<< " noTri=" << s_noTri
|
||||
<< "\n" << std::flush;
|
||||
}
|
||||
|
||||
if (triHit)
|
||||
{
|
||||
bestT = triBestT;
|
||||
@@ -2056,12 +2092,14 @@ int BTMechZoneAimPoint(void *mech, int zone, float out3[3])
|
||||
int BTMechSegmentPick(void *mech, const float ray_start[3], const float ray_dir[3],
|
||||
float max_range, float hit_out[3], int *zone_out)
|
||||
{
|
||||
// #131 contract: 1 = drawn-geometry hit, 0 = TRUE MISS (mesh tested),
|
||||
// -1 = no renderer/tree (caller may box-test as pre-tree grace).
|
||||
if (mech == NULL || application == NULL)
|
||||
return 0;
|
||||
return -1;
|
||||
BTL4VideoRenderer *renderer =
|
||||
(BTL4VideoRenderer *)application->GetVideoRenderer();
|
||||
if (renderer == NULL)
|
||||
return 0;
|
||||
return -1;
|
||||
return renderer->MechSegmentPick((Entity *)mech, ray_start, ray_dir,
|
||||
max_range, hit_out, zone_out);
|
||||
}
|
||||
|
||||
@@ -5584,12 +5584,30 @@ void
|
||||
Point3D hp;
|
||||
int zone = -1;
|
||||
float segHit[3];
|
||||
if (BTMechSegmentPick(m, rs, rd, 4000.0f, segHit, &zone))
|
||||
const int pickR = BTMechSegmentPick(m, rs, rd, 4000.0f, segHit, &zone);
|
||||
if (pickR > 0)
|
||||
{
|
||||
hp.x = segHit[0]; hp.y = segHit[1]; hp.z = segHit[2];
|
||||
}
|
||||
else if (!m->PickRayHit(rayStart, rayDir, 4000.0f, &hp))
|
||||
else if (pickR == 0)
|
||||
{
|
||||
// #131 MISS-MEANS-MISS: the drawn geometry was tested
|
||||
// and the ray missed -- NO lock. (The old AABB
|
||||
// fallback here answered with zone -1 and lit the
|
||||
// ring anyway: the box is far fatter than the
|
||||
// silhouette -- the second half of the false lock.)
|
||||
continue;
|
||||
}
|
||||
else if (!m->PickRayHit(rayStart, rayDir, 4000.0f, &hp))
|
||||
continue; // pickR < 0: no render tree yet -- the
|
||||
// box is the pre-tree replicant grace
|
||||
else if (getenv("BT_PICK_LOG"))
|
||||
{
|
||||
static int s_bx = 0;
|
||||
if ((++s_bx % 60) == 1)
|
||||
DEBUG_STREAM << "[pickbox] AABB grace hit #" << s_bx
|
||||
<< " (tree-absent replicant)\n" << std::flush;
|
||||
}
|
||||
float dx = hp.x - rs[0], dy = hp.y - rs[1], dz = hp.z - rs[2];
|
||||
float d = dx*dx + dy*dy + dz*dz;
|
||||
if (d < bestDist)
|
||||
@@ -5702,6 +5720,34 @@ void
|
||||
if (pickTarget != 0)
|
||||
targetReticle.rayIntersection = pickPoint;
|
||||
|
||||
// #131 LOCK-SWEEP readout: log every LOCK TRANSITION (the ring's
|
||||
// own condition -- a MECH in targetEntity) with the live twist, so
|
||||
// the sweep bench reads "lock ON at twist a .. OFF at twist b"
|
||||
// directly. Plus a 2 Hz heartbeat with zone + range.
|
||||
if (getenv("BT_LOCK_SWEEP"))
|
||||
{
|
||||
const int lockedNow = (hotTarget != 0
|
||||
&& pickTarget == hotTarget) ? 1 : 0;
|
||||
static int s_prevLock = -1;
|
||||
static float s_lsAcc = 0.0f;
|
||||
const float tw = (float)TorsoHeading();
|
||||
if (lockedNow != s_prevLock)
|
||||
{
|
||||
s_prevLock = lockedNow;
|
||||
DEBUG_STREAM << "[locksweep] " << (lockedNow ? "LOCK" : "unlock")
|
||||
<< " at twist=" << tw
|
||||
<< " zone=" << hotZone << "\n" << std::flush;
|
||||
}
|
||||
s_lsAcc += dt;
|
||||
if (s_lsAcc >= 0.5f)
|
||||
{
|
||||
s_lsAcc = 0.0f;
|
||||
DEBUG_STREAM << "[locksweep] hb lock=" << lockedNow
|
||||
<< " twist=" << tw << " zone=" << hotZone
|
||||
<< "\n" << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
// the engine-Entity target slots the whole weapon path reads
|
||||
if (pickTarget != 0)
|
||||
{
|
||||
@@ -6574,6 +6620,87 @@ void
|
||||
}
|
||||
}
|
||||
|
||||
// #131 LOCK-ENVELOPE PROBE (BT_LOCK_ENVELOPE=1): the symptom-shaped
|
||||
// measurement -- every ~2s, cast 49 rays from the eye toward the first
|
||||
// living target, yaw-offset -6..+6 deg in 0.25-deg steps, and print ONE
|
||||
// line: which source answered at each offset (T=triangle, S=sphere
|
||||
// fallback, B=whole-mech box, .=miss). The false lock reads directly:
|
||||
// S/B cells OUTSIDE the contiguous T band are lock-without-mech; misses
|
||||
// INSIDE it are no-reg-on-mech. Deterministic -- no servo, no spin.
|
||||
if ((Entity *)this == application->GetViewpointEntity()
|
||||
&& getenv("BT_LOCK_ENVELOPE"))
|
||||
{
|
||||
static float s_leT = 0.0f;
|
||||
s_leT += dt;
|
||||
if (s_leT >= 2.0f)
|
||||
{
|
||||
s_leT = 0.0f;
|
||||
extern int BTGetTargetCandidates(Entity *shooter, Entity **out, int maxOut);
|
||||
extern int BTIsRegisteredMech(Entity *e);
|
||||
extern int BTGetAimRay(float rx, float ry, float outStart[3], float outDir[3]);
|
||||
extern int BTMechSegmentPick(void *mech, const float s[3],
|
||||
const float dir[3], float max_range, float hit_out[3], int *zone_out);
|
||||
Entity *cand[8]; Mech *tgt = 0;
|
||||
int nc = BTGetTargetCandidates((Entity *)this, cand, 8);
|
||||
for (int ci = 0; ci < nc && tgt == 0; ++ci)
|
||||
if (cand[ci] != 0 && BTIsRegisteredMech(cand[ci])
|
||||
&& !((Mech *)cand[ci])->IsMechDestroyed())
|
||||
tgt = (Mech *)cand[ci];
|
||||
float rs[3], rdUnused[3];
|
||||
if (tgt != 0 && BTGetAimRay(0.0f, 0.0f, rs, rdUnused))
|
||||
{
|
||||
// bearing to the target's torso (origin + 5u up)
|
||||
float tx = (float)tgt->localOrigin.linearPosition.x - rs[0];
|
||||
float ty = ((float)tgt->localOrigin.linearPosition.y + 5.0f) - rs[1];
|
||||
float tz = (float)tgt->localOrigin.linearPosition.z - rs[2];
|
||||
float len = sqrtf(tx*tx + ty*ty + tz*tz);
|
||||
if (len > 1.0f)
|
||||
{
|
||||
tx /= len; ty /= len; tz /= len;
|
||||
char row[64];
|
||||
int nT = 0, nS = 0, nB = 0;
|
||||
for (int k = 0; k < 49; ++k)
|
||||
{
|
||||
// UNIT-based lateral sweep: -8..+8 u of miss distance
|
||||
// at the target's range (spheres inflate the lock
|
||||
// area in UNITS; a degree sweep degenerates at close
|
||||
// range -- operator caught the near-spawn scene).
|
||||
float lat = -8.0f + (16.0f / 48.0f) * (float)k;
|
||||
float rad = atan2f(lat, len);
|
||||
float c = cosf(rad), s = sinf(rad);
|
||||
float dir[3] = { tx*c + tz*s, ty, -tx*s + tz*c };
|
||||
float hp[3]; int zone = -1;
|
||||
int r = BTMechSegmentPick((void *)tgt, rs, dir, 4000.0f, hp, &zone);
|
||||
if (r)
|
||||
{
|
||||
// distinguish tri vs sphere: a sphere answer has
|
||||
// zone from segPick (>=0 possible) -- use the
|
||||
// [picksrc] counters for the split; here mark hits
|
||||
// vs the AABB probe below.
|
||||
row[k] = 'T'; ++nT;
|
||||
}
|
||||
else
|
||||
{
|
||||
Point3D bp;
|
||||
if (tgt->PickRayHit(
|
||||
Point3D(rs[0], rs[1], rs[2]),
|
||||
Point3D(dir[0], dir[1], dir[2]),
|
||||
4000.0f, &bp))
|
||||
{ row[k] = 'B'; ++nB; }
|
||||
else
|
||||
row[k] = '.';
|
||||
}
|
||||
}
|
||||
row[49] = 0;
|
||||
DEBUG_STREAM << "[lockenv] range=" << len
|
||||
<< " lat -8..+8u: " << row
|
||||
<< " (pick=" << nT << " box+=" << nB << ")\n" << std::flush;
|
||||
(void)nS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #124 PROBE (BT_ASPECT_TEST=1): the zero-premise frame probe. At frame
|
||||
// ~700, dispatch four self TakeDamage messages whose impact points sit
|
||||
// at KNOWN WORLD BEARINGS (+X/-X/+Z/-Z, 8 u out, torso height) around
|
||||
|
||||
@@ -604,6 +604,31 @@ void
|
||||
analogTwistAxis = s_forceTwist;
|
||||
}
|
||||
}
|
||||
// #131 LOCK-SWEEP (BT_LOCK_SWEEP=<axis 0..1>, default 0.12): pan the torso
|
||||
// in a slow triangle wave between the twist limits, so the REAL boresight
|
||||
// sweeps across a stand-off target and past both edges -- the operator-
|
||||
// visible lock-envelope instrument (watch the ring light/die; the
|
||||
// [locksweep] log in mech4 records the twist at each lock transition).
|
||||
{
|
||||
static float s_lockSweep = -1.0f;
|
||||
if (s_lockSweep < 0.0f)
|
||||
{
|
||||
const char *lsw = getenv("BT_LOCK_SWEEP");
|
||||
s_lockSweep = lsw ? (float)atof(lsw) : 0.0f;
|
||||
if (lsw != 0 && s_lockSweep <= 0.0f) s_lockSweep = 0.12f;
|
||||
if (s_lockSweep > 1.0f) s_lockSweep = 1.0f;
|
||||
}
|
||||
if (s_lockSweep > 0.0f)
|
||||
{
|
||||
effectiveTwistRate = baseTwistRate;
|
||||
// flip direction at the limits (small margin so we visibly cross
|
||||
// past the target and dwell OFF it at the extremes)
|
||||
static float s_dir = 1.0f;
|
||||
if (currentTwist >= horizontalLimitLeft - 0.05f) s_dir = -1.0f;
|
||||
if (currentTwist <= horizontalLimitRight + 0.05f) s_dir = 1.0f;
|
||||
analogTwistAxis = s_dir * s_lockSweep;
|
||||
}
|
||||
}
|
||||
|
||||
// TORSO GATE PROBE (BT_TORSO_LOG): why is the twist rate zero?
|
||||
if (getenv("BT_TORSO_LOG"))
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import sys
|
||||
sys.path.insert(0, r"C:\git\bt411\scratchpad\night7")
|
||||
import gitea
|
||||
|
||||
new_ids = {}
|
||||
|
||||
# ---------- NEW ISSUES ----------
|
||||
i = gitea.create(
|
||||
"Reticle shows LOCK with no mech under it + no-reg with reticle ON mech -- multiple testers, stationary targets; BLACKHAWK-correlated (774)",
|
||||
"""Source: playtest night 12 (2026-08-04, build **4.11.774 (8b887f6)**), Discord #play-testing.
|
||||
|
||||
Ronin (screenshots x2): "Showing lock without actually having reticle on mech" and the inverse "Reticle on mech, but no reg". Multiple testers reproduced on STATIONARY mechs. Conn Man: two more screenshots of an active reticle while not on the target. Oracle's correlation: "the blackhawk side torso panels are really weird ... It was the only one where several observed and reported the weird locking off the mech."
|
||||
|
||||
Draco's era memory (evidence, not confirmed): "I recall a slight delay that lock would stay as you moved crosshairs off" -- possible authentic lock-linger. Ronin's counter: multiple testers, stationary mechs, and BOTH directions (false lock off-mech AND no-reg on-mech), so linger alone does not explain it.
|
||||
|
||||
**Investigation leads [T4, flagged]:** 774 changed the pick twice (08-03 triangle-accurate + 08-04 patch-zone attribution). (a) The SPHERE FALLBACK still answers when the ray misses every triangle -- a ray that pierces cull spheres but no mesh returns a hit with a zone = "lock off-mech". (b) BTGetPickMesh returns NO TRIS for objects whose VB layout it cannot read -- those segments are invisible to the triangle pass and fall to spheres; if the BLACKHAWK's meshes trip this, both symptoms concentrate there ("no reg" on-mesh where tris are missing + sphere lock off-mesh). [picktri]/BT_PICK_LOG logs the NO TRIS case. (c) What drives the LOCK UI (PipColor/TargetWithinRange attrs) vs the pick designation -- they may disagree.
|
||||
|
||||
Field logs from the night are staged (scratchpad/night12/, 3 players). First step: bench a blackhawk target with BT_PICK_LOG and count NO TRIS + sphere-fallback picks.""",
|
||||
labels=[1,2])
|
||||
new_ids['reticle'] = i['number']
|
||||
|
||||
i = gitea.create(
|
||||
"Persistent YELLOW LINE on the HUD in every mech (Conn Man, 774)",
|
||||
"""Playtest night 12 (774). Conn Man: "I also have a yellow line on my HUD that was in every mech I piloted tonight" (screenshots in Discord). Machine MS-FIREFLY (user santo); his log is staged in scratchpad/night12/. Not reported by other testers so far -- may be layout/aspect specific.""",
|
||||
labels=[1,4])
|
||||
new_ids['yellowline'] = i['number']
|
||||
|
||||
i = gitea.create(
|
||||
"Do generators X out on the MFD when shut down / overheated? (era-behavior question)",
|
||||
"""Oracle, night 12: "I don't think they are X'ing out when overheated / when shutting down / can't remember if they only X out when destroyed." Operator does not know the proper behavior either. Needs grounding: the manual + the gauge stream (engineering panel X-out overlay conditions -- destroyed only, or also offline/thermal-breaker states?). Pure authenticity question before any code is touched.""",
|
||||
labels=[2,4])
|
||||
new_ids['genx'] = i['number']
|
||||
|
||||
i = gitea.create(
|
||||
"Panic eject carries NO score penalty (774) -- death-without-honor cost not observed",
|
||||
"""Oracle, night 12, twice: "my score did not go negative" / "Panic test - It worked but there is no penalty on the score." The #118 tail shipped a death score cost + the DeathWithoutHonor console notice (1efe8ef); the notice ("dunce cap") IS confirmed working, the SCORE COST is not observed. Candidates: the cost never applies, applies to a different counter, or the scoreboard clamps at zero and Oracle was at 0. Check the cost path vs the score attribute the KILLS panel reads, then bench a panic with a positive score.""",
|
||||
labels=[1])
|
||||
new_ids['penalty'] = i['number']
|
||||
|
||||
i = gitea.create(
|
||||
"Coolant leak with NO flashing annunciators -- normal (non-glass) screen mode (RajelAran, 774)",
|
||||
"""RajelAran, night 12: "Had a coolant leak with no flashing at the end of the last match. I'm running in normal screen mode, NOT glass." His log is staged (scratchpad/night12/, GAMERSLAB). Distinct from the glass-window throttling item (that one is glass-specific and root-caused); this is the docked/normal layout. Compare his log's [techstat]/lamp lines around the leak window.""",
|
||||
labels=[1,4])
|
||||
new_ids['leaklamp'] = i['number']
|
||||
|
||||
i = gitea.create(
|
||||
"Leaking loop responds to COMPONENT coolant toggles while the loop is SHUT -- leak/alarm stops and restarts with component toggle (774)",
|
||||
"""RajelAran, night 12: "toggling off components on a leaking loop after shutting off the loop would shut off the leak and alarm, and toggling the components back on would cause the loop to start leaking again even when shut. No leak indicators were present on the components. Not clear whether effects were coincidental, will try to replicate tomorrow." Awaiting his repro; when it lands, bench with the valve/heat-family logs. May be authentic plumbing (component flow draws through a shut loop?) -- ground in the heat-family decomp before calling it a bug.""",
|
||||
labels=[2])
|
||||
new_ids['leaktoggle'] = i['number']
|
||||
|
||||
i = gitea.create(
|
||||
"Respawn came back with MYOMERS heat MAXED, dumping into coolant loop 5 (Oracle, 774)",
|
||||
"""Oracle, night 12, final drop: "I had a respawn where my myomers started overheated (maxed) and dumped all their heat into the cool loop 5 which then became moderately warm." One occurrence. The respawn-reset audit (RESPAWN_REARM_PLAN addendum) verified valves/coolant/gen resets, and the heat family has DeathReset coverage since #55 -- so either the myomer heat member misses the reset chain, or the heat arrived post-spawn (gimp/overdrive in the drop). Check the myomer RTIS body vs the binary and Oracle's staged log at the respawn timestamp.""",
|
||||
labels=[1,2])
|
||||
new_ids['myoheat'] = i['number']
|
||||
|
||||
i = gitea.create(
|
||||
"Glass panels: Windows throttles unfocused windows' repaint timer -- buttons flash at 0.166 Hz unless a window is dragged (Cyd fixing)",
|
||||
"""Oracle, night 12: "Buttons still flash at .166 Hz in glass cockpit. Flash at normal rate if I drag a window" + earlier "all buttons flash at correct rate if I drag a window." Cyd root-caused same night: "windows deprioritizing non-focused windows, fixing..." -- the 62ms WM_TIMER repaint in the per-display glass windows gets throttled by Windows for unfocused windows, so the wall-clock flash animation only samples ~every 6s. Cyd has the fix in progress (also adding vPlasma noframe to the .cfg + making the 0x3D panic button red). This issue tracks his branch landing.""",
|
||||
labels=[1,4,3])
|
||||
new_ids['glassflash'] = i['number']
|
||||
|
||||
# ---------- CLOSES with receipts ----------
|
||||
gitea.close(124, """**FIELD-ACCEPTED -- closing (night 12, 774).** Oracle re-ran the audit: "targetting is super precise right now ... I can move a few pixels over on the panel lines and it detects perfectly on all panels." Full chassis sweep ALL PASS: Thor, Sunder, Madcat, Avatar, Loki, Vulture (incl. searchlight panel), Owens, Blackhawk. The per-panel patch-zone model (the 08-04 correction) is the accepted behavior. Residuals filed separately: the Blackhawk side-torso weirdness + reticle false-lock (#%d), which correlate and get their own dig.""" % new_ids['reticle'])
|
||||
|
||||
gitea.close(16, "Subsumed by the #124 field acceptance (night 12, 774): per-panel precision verified on all 8 chassis -- the one-band-low signature is gone. Closing.")
|
||||
|
||||
gitea.close(73, "Closing against the #124 field acceptance (night 12, 774): aimed damage credits the exact panel under the reticle on all chassis (Oracle: 'detects perfectly on all panels'). The original 'aimed at right arm, reported elsewhere' cannot survive that matrix; the weighted-lottery base rate note stands for unaimed weapons.")
|
||||
|
||||
gitea.close(87, """**FIELD-VERIFIED -- closing (night 12, 774).** Oracle: "armor panels are darkening and smoke is emitting properly ... Darkened panels showing and showing consistently? Yes including smoke of varying intensities being emitted as well from those damaged panels. Working very well." All 8 chassis.""")
|
||||
|
||||
gitea.close(129, "FIELD-VERIFIED -- closing (night 12, 774). Oracle's checklist: 'Smoking mech on respawn? None observed. Good.'")
|
||||
|
||||
gitea.close(92, "FIELD-VERIFIED -- closing (night 12, 774). Loki full armor-panel pass ('Avatar and Loki armor are perfect'); the foot zones resolve + take damage per the #124 per-panel matrix and the zone-walk bench receipts earlier on this issue.")
|
||||
|
||||
gitea.close(91, "FIELD-VERIFIED -- closing (night 12, 774). Oracle: 'thor bowtie worked' -- the pod-plate renders as cockpit structure. Reopen if Ronin (the detailed reporter) sees otherwise on his rig.")
|
||||
|
||||
gitea.close(55, """FIELD-VERIFIED -- closing (night 12, 774). Oracle: "confirm all coolant loops reset on respawn with panic / and gen assignments remain" + checklist "Valves reset on respawn? Yes. We are hearing the balance coolant loop sound when respawning. Gen assignments and seek levels remain on respawn? Yes." The one respawn-heat anomaly from the night (myomers maxed on spawn) is filed separately (#%d) -- single occurrence, distinct mechanism.""" % new_ids['myoheat'])
|
||||
|
||||
gitea.close(68, "FIELD-VERIFIED -- closing (night 12, 774). Oracle: 'Someone trying to join with wrong build - Works.' The build-gate rejection is player-visible (message box with both versions) instead of the silent exit this issue reported.")
|
||||
|
||||
gitea.close(118, """**FIELD-VERIFIED -- closing the core (night 12, 774).** Oracle's checklist: Panic arms + works on ALL THREE authored conditions -- coolant bleed-out, all 4 generators offline, leg-gimp (Novice only). Respawn cycle clean. The DeathWithoutHonor notice ("dunce cap") confirmed working. The one missing tail -- NO SCORE PENALTY observed -- is filed as its own bug (#%d) so this monster can finally close. Operator note from the night: the panic arm reads as a subtle color change, could be more obvious -- Cyd already made the 0x3D button red on his branch.""" % new_ids['penalty'])
|
||||
|
||||
# ---------- COMMENTS / sightings ----------
|
||||
gitea.comment(52, """Night 12 (774) sightings -- skating is BACK (or never fully left): Oracle saw Ronin skating ~9:50 PM ET, RajelAran ~10:15 PM ET, and Sauron in the final drop. Three distinct victims in one night. Field logs staged (scratchpad/night12/, 3 players incl. two of the observers); the new [ghost]/GHOST forensics shipped in this build, so if any skater's replicant was record-starved the logs will say -- if they were receiving records while skating, this is the gait-replication path (#130 family), not starvation.""")
|
||||
|
||||
gitea.comment(24, "Night 12 (774): RajelAran's hat stuck to the right again -- POV changed views but re-centered back to the right; wiggling the hat several times cleared it. New data: recovery IS possible now (the original report had no recovery), so the stuck state is a latched axis, not a latched mode.")
|
||||
|
||||
gitea.comment(108, """Night 12 (774) status: the build gate held (a wrong-build join was rejected, visibly) so the version-skew confound is retired in the field. NO ghost-mech report tonight across a full session -- the night's replication anomaly was SKATING (#52, three sightings), which is a different signature (mech moves but slides; a ghost is a dead mech never removed). The [ghost]/GHOST forensics were live in every player's log; staged logs (scratchpad/night12/) get scanned next.""")
|
||||
|
||||
print("NEW:", new_ids)
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
# #92 check: is the Loki foot un-hittable report (night 7, build 659) already
|
||||
# cured by the #124 triangle-pick work? The zone-walk matrix vs a BLACKHAWK target (#131 false-lock forensics):
|
||||
# shooter servo-aims every zone (feet included) through the real reticle path,
|
||||
# 3 laser pulses each; read A's [walk] FIRE lines vs B's [dmghit] zone= lines.
|
||||
# Same rig as scratchpad/night10/zonewalk.sh, target vehicle=loki, ~7 min tail.
|
||||
set -x
|
||||
. /c/git/bt411/scratchpad/night6/bench_common.sh
|
||||
cd /c/git/bt411/content || exit 1
|
||||
bt_assert_player_env
|
||||
taskkill //F //IM btl4.exe > /dev/null 2>&1
|
||||
sleep 2
|
||||
rm -f zwb_a.log zwb_b.log
|
||||
bt_expert_egg MP.EGG ZWB.EGG
|
||||
sed -i "s/^map=.*/map=grass/; s/^time=.*/time=day/" ZWB.EGG
|
||||
# pilot 1 (node A, shooter) = madcat (proven servo constraints);
|
||||
# pilot 2 (node B, target) = LOKI (the #92 chassis)
|
||||
python - << 'EOF'
|
||||
lines = open('ZWB.EGG').read().splitlines(True)
|
||||
n = 0
|
||||
for i, l in enumerate(lines):
|
||||
if l.startswith('vehicle='):
|
||||
n += 1
|
||||
lines[i] = 'vehicle=madcat\n' if n == 1 else 'vehicle=bhk1\n'
|
||||
open('ZWB.EGG', 'w').writelines(lines)
|
||||
print('vehicles set:', n)
|
||||
EOF
|
||||
|
||||
BT_SPIN_SELF=15 BT_DMG_LOG=1 BT_DEATH_LOG=1 BT_MP_LOG=1 \
|
||||
bt_launch zwb_b.log ZWB.EGG 0x0C -net 1601
|
||||
sleep 2
|
||||
BT_ZONE_WALK=6 BT_PICK_LOG=1 BT_GOTO=enemy BT_GOTO_STOP=90 BT_KEY_NOFOCUS=1 \
|
||||
BT_DMG_LOG=1 BT_RANGE_LOG=1 BT_MP_LOG=1 \
|
||||
bt_launch zwb_a.log ZWB.EGG 0x03 -net 1501
|
||||
sleep 5
|
||||
python ../tools/btconsole.py ZWB.EGG 127.0.0.1:1501 127.0.0.1:1601 > zwb_relay.log 2>&1 &
|
||||
sleep 300 # ~7 min: enough for a full zone walk incl. both feet
|
||||
Reference in New Issue
Block a user