Files
BT411/scratchpad/night6/file_73finding.py
T

69 lines
4.1 KiB
Python

"""#73: post the zone-lottery discovery."""
import base64
import json
import subprocess
import urllib.request
REPO = r"C:\git\bt411"
BASE = "https://gitea.mysticmachines.com/api/v1/repos/VWE/BT411"
out = subprocess.run(["git", "credential", "fill"],
input="protocol=https\nhost=gitea.mysticmachines.com\n\n",
capture_output=True, text=True, cwd=REPO)
cred = dict(l.split("=", 1) for l in out.stdout.strip().splitlines() if "=" in l)
AUTH = "Basic " + base64.b64encode(
(cred["username"] + ":" + cred["password"]).encode()).decode()
def call(method, path, payload=None):
data = json.dumps(payload).encode() if payload is not None else None
r = urllib.request.Request(BASE + path, data=data, method=method)
r.add_header("Authorization", AUTH)
r.add_header("Content-Type", "application/json")
return json.load(urllib.request.urlopen(r))
BODY = """**INVESTIGATED 2026-07-29 -- this is mostly the authentic 1995 model, not a bug.**
The zone a hit credits is chosen by a **weighted lottery**, in binary-faithful code reading binary-shipped tables (`dmgtable.cpp`, stream format byte-verified):
1. impact point -> mech-local
2. **height layer**: `floor(layerCount * y / heightRef)`
3. **pie slice**: `atan2(z, x)` around the mech's vertical axis (a layer can rotate with live torso twist -- `rotateWithTorso`)
4. `DamageZonePercentTable::SelectZone()` = **`RandomUnit()` rolled against cumulative percent thresholds** (`@0x49de14`) -- each slice carries an authored *distribution* of zones
So aiming at the left arm at best biases WHICH SLICE the impact lands in; the zone within that slice is dice, by design. "Fired only at the left arm, damage reported all over the doll, no crits" is what this model produces. **Pixel-precise limb damage never existed in Tesla 4.10.**
Bench measurement (solo dummy, walked to 8u, aim pinned left / center / right across the silhouette, trigger held, `BT_DMG_LOG`):
```
aim LEFT 24 hits -> zones 15(x9) 12(x6) 2(x3) 14(x2) 9 21
aim CENTER 46 hits -> zones 2(x11) 13(x9) 7(x6) 6(x5) 21(x5) 0(x5)
aim RIGHT 45 hits -> zones 21(x9) 17(x7) 0(x7) 9(x6) 18(x5) 15(x5)
```
Scatter within one aim point = the percent tables. The distribution SHIFTING with aim = the slice selection responding. Both halves of the model visibly working.
@VGL-Lynx's LOD theory: right instinct (hit-test geometry != drawn mesh), wrong geometry -- it is not LOD-dependent. The port's pick ray tests the **whole-mech bounding BOX** (`Mech::PickRayHit`, an AABB slab test), and the binary's own pick code was never decompiled (the `0x37c/0x388/0x38c` writer sits in an un-exported gap), so the box is a port stand-in of unknown fidelity.
**The one residual question that IS potentially a real port bug:** theta computed from a flat box FACE clusters toward the slices facing the shooter, so FLANK slices (where arm-heavy percent tables presumably live) may be under-reachable from frontal shots compared with the pod -- which plausibly intersected the mech's *cylinder* (the damage table is literally cylindrical). Settling it needs:
- a per-hit probe logging `theta / layer / slice` (extend `BT_DMG_LOG`)
- a one-shot wheel dump for one mech (slices per layer + each slice's {percent, zone} entries + zone names)
If the wheel dump shows arm zones concentrated in flank slices AND the theta probe shows frontal shots cannot reach those slices, the fix is a ray-vs-cylinder pick (radius from the collision extents) replacing the box slab -- cylinder-consistent with the table the binary ships. If arm zones appear in the front slices' tables too, the field report is 100%% authored behavior and this closes as by-design.
Recommend telling the testers now that per-limb aiming is not how this game's damage works -- it will save another evening of controlled experiments chasing the lottery."""
def main():
marker = BODY.strip().splitlines()[0][:60]
for c in call("GET", "/issues/73/comments"):
if marker in c.get("body", ""):
print(" #73 already has this comment - skipped")
return
call("POST", "/issues/73/comments", {"body": BODY})
print(" commented on #73")
main()