scoring: mech+0x354 is VESTIGIAL -- label it so nobody "finishes" it
MECH_DAMAGE_BIAS(m) returned 0.0f under a comment reading "bring-up: factor =
0*bias+1 = 1", which invites a future session to wire it up. Auditing
Mech::Reset settled what it actually is, and 0.0f turns out to be EXACT:
* mech+0x354 has exactly ONE writer in the image -- Mech::Reset (@0049fb74,
part_012.c:14340). Nothing touches it during play.
* Reset computes mean(zone + 0x158) across every damage zone, AFTER the zone
heal has already zeroed those cells. So it is ~0 the moment it is written,
stays ~0 for the mech's whole life, and is recomputed as ~0 next respawn.
* It has exactly ONE reader -- CalcInflictedScore (@004c052c,
part_013.c:19055) -- as `avg * role.damageBias + 1.0`.
So the factor is 1.0 for the entire game and the stand-in reproduces the
binary exactly. 0x358 and 0x35c are the same computation over subsystem zones
and have NO reader at all.
This also raises confidence in the night-13 scoring work: the 505.88 kill award
was not right DESPITE a missing term -- the term genuinely is 1.0. Wiring
0x354 to live accumulated damage would silently inflate every inflicted and
kill award, and both chart-verified numbers (+1 a damage point, +500 a kill)
assume 1.0.
Comment rewritten at the macro; combat-damage.md carries the same finding [T1].
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NCJQkvq6G2JNrpVbA75tVZ
This commit is contained in:
co-authored by
Claude Opus 5
parent
1f0923747b
commit
5b7e481913
@@ -666,6 +666,16 @@ credits cross-node correctly: its value rides `scoreAward`. **Fix shape:** compu
|
||||
victim's node (where the damage data is) and ship the RESULT in `scoreAward`, as the kill report
|
||||
does — do not ship the basis and recompute where it cannot be seen.
|
||||
|
||||
**The damage-bias term is VESTIGIAL — do not "finish" it** [T1, audit 2026-08-08]. The kill/inflicted
|
||||
formula's `(victimAvgZoneDamage@0x354 × damageBias + 1.0)` factor is **always 1.0** in the shipped
|
||||
binary. `mech+0x354` has exactly one writer — `Mech::Reset` (@0049fb74, part_012.c:14340), which
|
||||
computes `mean(zone+0x158)` across every damage zone *after* the zone heal has zeroed those cells —
|
||||
and exactly one reader, `CalcInflictedScore` (@004c052c). Nothing recomputes it during play, so it
|
||||
holds ~0 for the mech's whole life. `0x358`/`0x35c` are the same computation over subsystem zones
|
||||
and have **no reader at all**. The port's `MECH_DAMAGE_BIAS(m) → 0.0f` therefore reproduces the
|
||||
binary exactly; wiring it to live damage would look like completing a stub and would silently
|
||||
inflate every award (the chart-verified +1/point and +500/kill both assume 1.0).
|
||||
|
||||
⚠ **Three chart rows are NOT yet reconciled with the reconstruction** — treat as open [T4]:
|
||||
(a) a kill benches at `award=4.88`, two orders off the chart's flat **+500**; (b) **+1000 at
|
||||
game start** has no known implementation; (c) **−1000 eject / −500 ammo** would live in
|
||||
|
||||
@@ -305,7 +305,29 @@ static const Scalar TicksPerSecond = 1.0f; // (see note in PlayerSimulation)
|
||||
// tonnage ratio stubbed 1.0 + damage bias stubbed 0.0 for bring-up (SCORE == raw
|
||||
// damage, un-tonnage-scaled; the real per-mech tonnage/bias accessors are a follow-up).
|
||||
#define MECH_TONNAGE(m) (1.0f) // bring-up: ratio == 1
|
||||
#define MECH_DAMAGE_BIAS(m) (0.0f) // bring-up: factor = 0*bias+1 = 1
|
||||
// mech+0x354 -- the score formula's per-target damage-bias factor.
|
||||
//
|
||||
// ⚠ DO NOT "FINISH" THIS. 0.0f is not a stand-in; it is the value the shipped
|
||||
// binary always has, established by audit 2026-08-08:
|
||||
//
|
||||
// * mech+0x354 has exactly ONE writer in the whole image -- Mech::Reset
|
||||
// (@0049fb74, part_012.c:14340). Nothing touches it during play.
|
||||
// * Reset computes it as mean(zone + 0x158) across every damage zone, and it
|
||||
// does that AFTER the zone heal has already zeroed those cells. So it is
|
||||
// ~0 the instant it is written, stays ~0 for the mech's entire life, and is
|
||||
// recomputed as ~0 on the next respawn.
|
||||
// * It has exactly ONE reader -- CalcInflictedScore (@004c052c,
|
||||
// part_013.c:19055) -- where it appears as `avg * role.damageBias + 1.0`.
|
||||
//
|
||||
// So the factor is 1.0 for the whole game, and returning 0.0f here reproduces
|
||||
// the binary EXACTLY. It is a vestigial aggregate (0x358 and 0x35c are the
|
||||
// same computation and have NO reader at all).
|
||||
//
|
||||
// Wiring this to live accumulated damage would look like completing an unfinished
|
||||
// port and would silently inflate every inflicted and kill award -- the numbers
|
||||
// verified against the original manual's scoring chart (+1 a damage point, +500
|
||||
// a kill) all assume this term is 1.0.
|
||||
#define MECH_DAMAGE_BIAS(m) (0.0f) // = the binary's value; see above
|
||||
#define MECH_OWNING_PLAYER(m) ((BTPlayer *)((Mech *)(m))->GetPlayerLink()) // ENTITY.h:430 (NULL for the dummy)
|
||||
|
||||
//#############################################################################
|
||||
|
||||
Reference in New Issue
Block a user