A replicant could not start walking between gait-change records. The port's
body case 4 (the task-#64 lockstep twin) is an INSERTION sitting between case 0
and the advance group; in the binary case 4 is a MEMBER of that group
(FUN_004a5678 @004a5678: case 2,3,4,5,8,... -- no turn block, no speed exit),
so case 0's fallthrough is meant to land on Advance(). The insertion caught it.
On a replicant that is not a race but an identity: case 0 arms walk iff
standSpeed < bodyTargetSpeed, and the inserted block resets iff standSpeed <
bspd -- where bspd IS bodyTargetSpeed for a replicant. Same expression, so arm
and reset fire on the same frame, forever, and a peer parked at Standing with a
live replicated demand never cycles. bodyCycleSpeed stays 0 while position
advances from dead reckoning: the skate.
This is the sequel to e91d447 (#82). Before it the replicant branch read the
dead local mapper cell (0 forever), the exit never fired, and the fallthrough
worked BY ACCIDENT. Fixing the dead cell closed the escape hatch.
Fix: case 0 -> goto advance_body_normally, the leg twin's own idiom, restoring
the binary's structure without touching the #64/#82 turn logic.
BT_NO_BODY_FALLTHRU=1 reverts.
Measured (2-node, scratchpad/night13/skatelock.sh):
legacy 336 consecutive locked seconds, bspd=39.2324 bts=39.2324 every line
fixed 0 locks, every pass
master body-Standing samples 52 -> 21 (it locked too, invisibly at mj=0)
turn-in-place intact: pivoter body state 4 x9 / leg state 4 x8, in lockstep
Diagnostics (both keepers): [skate] now carries bstate= -- the field lines
proved "both channels idle" but never named the state, which was the whole
answer; [bodySM]/[peergait] under BT_BODY_SM_LOG instrument the arm->reset pair
and a moving replicant's body channel.
NOT claimed: that this accounts for the night-13 field episodes. That link is
inference -- locked + translating IS the skate signature by construction, but no
bench caught the two together. bstate= settles it next playtest.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NCJQkvq6G2JNrpVbA75tVZ
144 lines
9.4 KiB
Python
144 lines
9.4 KiB
Python
"""Night 13 (2026-08-06, build 4.11.817) tracker housekeeping. ASCII only."""
|
|
import sys
|
|
sys.path.insert(0, r"C:\git\bt411\scratchpad\night7")
|
|
import gitea
|
|
|
|
BUG, INV, WIP, HUD, AUDIO, NET, WORLD, AWAIT = 1, 2, 3, 4, 5, 6, 7, 8
|
|
SRC = ("Source: playtest night 13 (2026-08-06, build **4.11.817 (6fcff95+)**), "
|
|
"Discord #play-testing. Field logs staged in `scratchpad/night13/` "
|
|
"(4 players + the pod cart).\n\n")
|
|
new = {}
|
|
|
|
# ---------------------------------------------------------------- NEW ISSUES
|
|
i = gitea.create(
|
|
"REGRESSION (817): BT_GLASS_LAYOUT=save writes a layout file with the MFD and Secondary lines MISSING",
|
|
SRC +
|
|
"SAURON (Michael), repeatedly: \"the save command is no longer writing to the glass_layout.cfg "
|
|
"file since this latest build\" ... \"got my glass panels set, saved and borders off again now\" "
|
|
"-> \"and then relaunched and it reset again\" -> \"looks like it rewrote the glass_layout.cfg "
|
|
"again\".\n\n"
|
|
"**The diagnostic detail:** \"the glass_layout.cfg had all the MFDs and secondary lines missing, "
|
|
"but plasma was still there\". So `save` is not failing to write -- it writes a file in which the "
|
|
"MFD and Secondary/Radar entries are simply absent, and the Plasma entry survives. On the next "
|
|
"launch there is nothing to restore, so every panel resets and the border/bare state is lost too.\n\n"
|
|
"**Workaround (confirmed by SAURON):** set `BT_GLASS_LAYOUT=load` and restore a hand-kept backup "
|
|
"copy of `glass_layout.cfg` -- \"set to load and used backup copy of CFG file and working aok so far\".\n\n"
|
|
"Probably the same root cause: vwe_propwash the same night -- \"my screen order borked again so "
|
|
"I'll need the trick to re-align them\".\n\n"
|
|
"**Suspect [T4, unverified]:** today's pod-MFD work is the only thing that touched this area. "
|
|
"Candidates, in order: (a) `e179c70` / `67a4f09` -- `BT_POD_RGB` and the bare-panel mode changed "
|
|
"how panel surfaces are enumerated and added the new `monitor:<name|index>` and `,bare` line "
|
|
"forms, so the WRITER may no longer emit a line for a surface it cannot express (or the panel "
|
|
"list it walks is now populated differently); (b) `d213c98` -- panel create/destroy moved out of "
|
|
"the PadRIO ctor into `LBE4ControlsManager`, which changes panel LIFETIME: if the save runs after "
|
|
"`BTGlassPanels_Destroy()`, the windows are already gone and there is nothing to serialize, which "
|
|
"would explain exactly this signature (Plasma is not a glass panel and is destroyed elsewhere, so "
|
|
"it alone survives).\n\n"
|
|
"Related: #76 (main cockpit + Plasma positions not restored) -- that is the older, much smaller "
|
|
"version of this; fix this one first, #76 may be a subset. Desktop glass mode only; the pod cart "
|
|
"is unaffected because it runs `BT_GLASS_LAYOUT=load` off a frozen master.",
|
|
labels=[BUG, HUD])
|
|
new['layoutsave'] = i['number']
|
|
|
|
i = gitea.create(
|
|
"Missiles launch along the LEG/FOOT facing, then curve to the target -- peer POV only",
|
|
SRC +
|
|
"Oracle: \"the missile thing we observed where missiles are firing in the direction the mech feet "
|
|
"are facing\" ... \"and then coming around to track the target\" ... \"**the emitter is following "
|
|
"the foot facing**\".\n\n"
|
|
"Confirmed by Oracle as **peer POV only** (epilectrik: \"only from peer pov though right\" -> "
|
|
"\"yes correct\"): from your own cockpit the launch looks right; on a REPLICANT the launch vector "
|
|
"comes off the leg/hip yaw instead of the torso/turret yaw. The homing itself works -- the missile "
|
|
"curves onto the target after launch -- so this is the muzzle/emitter TRANSFORM on the replicated "
|
|
"mech, not the guidance.\n\n"
|
|
"Reads as the replicant's weapon hardpoint being attached to (or composed against) the wrong node "
|
|
"in the segment hierarchy -- the leg/root segment rather than the twisted torso. Compare against "
|
|
"the master-side emitter, which is correct.\n\n"
|
|
"Related: #37 (MadCat torso is BACKWARDS), #70 (torso twist stops working after respawn) -- all "
|
|
"three are torso-yaw composition on a replicated model, and may share a cause.",
|
|
labels=[BUG, NET])
|
|
new['missiledir'] = i['number']
|
|
|
|
i = gitea.create(
|
|
"CROUCH does not toggle: the lamp flashes on every press but the mech stays STANDING",
|
|
SRC +
|
|
"Reported by Oracle and previously by SAURON. Oracle: \"the crouch button did not toggle to "
|
|
"display crouched\" ... \"no state change\" ... \"button flickers sometimes on press, **the light "
|
|
"next to it always flashes when pressed**, but state does not change. Remains in stand mode\".\n\n"
|
|
"So the INPUT is arriving and the annunciator responds -- the press is seen all the way to the "
|
|
"lamp -- but the crouch state itself never changes. That narrows it to the state transition / "
|
|
"gait request rather than the button wiring.\n\n"
|
|
"**Not to be confused with (and NOT a bug):** throttle-up does not stand you back up. Settled this "
|
|
"night by primary source -- Lynx, quoting the original manual: \"Throttle up should not make you "
|
|
"stand. Verified in manual. You must push the button again to stand. I agree that throttle up "
|
|
"'should' do that, but it's not designed that way.\" Standing requires a second CROUCH press, "
|
|
"which makes this bug worse than it looks: with no working toggle there is no designed way out of "
|
|
"crouch. Locomotion/CROUCH background: `context/locomotion.md`.",
|
|
labels=[BUG])
|
|
new['crouch'] = i['number']
|
|
|
|
i = gitea.create(
|
|
"One panel hit makes smoke erupt from MULTIPLE/ALL locations at once (seen on the sensor special panel)",
|
|
SRC +
|
|
"Oracle: \"the smoke sometimes emitting from multiple locations all at once when a location like "
|
|
"the sensor special panel is hit during testing. I saw this several times. It's not just with the "
|
|
"special panel, but it might have something to do with reaching a certain damage threshold which "
|
|
"is fairly easy to do quickly with a special panel. So you hit the special with an alpha and "
|
|
"suddenly the entire target mech emits smoke from all panels.\"\n\n"
|
|
"**Open question from the reporter, and the key discriminator:** \"What I'm not sure about is if "
|
|
"it's emitting only from previously damaged panels.\" If it is only previously-damaged panels, "
|
|
"this is a threshold that re-triggers the effect on every already-damaged zone at once (a "
|
|
"retrigger/latch bug). If it is genuinely ALL panels, the emitter is being attached per-mech "
|
|
"instead of per-zone. Answer that first -- it picks the fix.\n\n"
|
|
"Suspected trigger is a whole-mech damage THRESHOLD being crossed rather than the specific zone, "
|
|
"which a special-panel alpha reaches quickly.\n\n"
|
|
"Related: #90 (flames/smoke render less often and shorter than the original), #114 (missile impact "
|
|
"smoke too thick), #129 (closed: respawned mech emitted the wreck plume) -- same damage-effect "
|
|
"emitter family.",
|
|
labels=[BUG, INV])
|
|
new['smokeall'] = i['number']
|
|
|
|
i = gitea.create(
|
|
"No SPLASH damage from a PANIC/EJECT/suicide death (splash from normal deaths now confirmed working)",
|
|
SRC +
|
|
"SAURON: \"Splash damage looked good to me, splash worked on mechs that died close, **but no "
|
|
"splash on a panic / eject / suicide death**.\"\n\n"
|
|
"Filed as the leftover sub-case of #89, which is otherwise verified working this night and closed.\n\n"
|
|
"**Authenticity is NOT established** -- do not 'fix' this before deciding what the original did. A "
|
|
"panic eject is plausibly a different death path (the pilot leaves; whether the chassis still "
|
|
"detonates with an explosion payload is an open era question), so a self-destruct that does no "
|
|
"splash could be correct. Decide from the binary's eject/death path first: does the eject route "
|
|
"raise the same explosion object as a combat death, and does that object carry the splash payload?\n\n"
|
|
"Related: #89, #106 (closed: splash burstCount dropped), #118/#109 (EJECT/PANIC wiring), #134 "
|
|
"(closed: panic eject score penalty).",
|
|
labels=[INV])
|
|
new['ejectsplash'] = i['number']
|
|
|
|
i = gitea.create(
|
|
"ThermalSight / IR ('predator vision'): the VISIBLE half is unimplemented -- and it was never a heat image",
|
|
SRC +
|
|
"epilectrik: \"IR we solved but I think haven't implemented yet\" -- decode exists, presentation "
|
|
"does not, and there was no tracker item for the visible half (#61 covers the dead ToggleLamp "
|
|
"handler; #123 is the same shape for the searchlight).\n\n"
|
|
"**Primary-source description of what it should look like** -- Oracle, who played the original "
|
|
"pods at Lazer Park, this night:\n"
|
|
"- \"the IR was not what you would expect ... it was called predator vision, but it just looked "
|
|
"more like a **random palette shift**\"\n"
|
|
"- \"it was **not a heat image**\"\n"
|
|
"- \"which is why we generally called it LSD vision in Lazer Park\"\n"
|
|
"- \"IMHO it did nothing to improve visibility. All I found was that you had to look for some "
|
|
"movement and go after that\"\n"
|
|
"- epilectrik's recollection: it was a **test mode in the TH division hardware** that they "
|
|
"switched on, so it was not a specifically designed effect. Oracle: \"hardware optimized\".\n\n"
|
|
"**Why this matters for the port [T3]:** do not build a thermal/heat-gradient shader. The target "
|
|
"is a palette/colour-table transform on the existing image -- most likely whatever the 1995 "
|
|
"hardware path did when its test mode was enabled. Scope it from the decomp (and, if it really is "
|
|
"a hardware mode, decide what the honest modern equivalent is) before writing anything.\n\n"
|
|
"Related: #61 (ThermalSight ToggleLamp), #123 (searchlight visible half -- the same "
|
|
"toggle-works/presentation-deferred split).",
|
|
labels=[INV, WORLD])
|
|
new['ir'] = i['number']
|
|
|
|
print()
|
|
print("NEW:", new)
|