Harden Papyrus marshaling boundary and add per-hit diagnostics - #2
Open
kotarf wants to merge 1 commit into
Open
Conversation
Hit-zone classification is unchanged (verified bit-for-bit against the previous math over a scenario sweep and 2000 fuzzed inputs). Changes: - GetHitZone validates array lengths before indexing. CommonLibSSE turns a None or short Papyrus array into an empty/short std::vector, and the old d[5]/p[4]/s[5] reads were undefined behaviour in that case. Now logs an error and returns 0. - Compute all pitch thresholds and lateral ranges up front, then emit one trace line per hit with every input and threshold so real in-game values can be captured when debugging misclassified hits. - Warn when dist is not positive or when asin() produces NaN (dispWidth/dx outside [-1,1]); NaN ranges silently fall through to chest/back. - Use std::fabs instead of unqualified abs on floats. MSVC's ucrt resolves abs(float) to the float overload, but a conforming libstdc++ picks abs(int) and truncates. - ArmHitCalcSKSE takes float armRange (matches Papyrus Float and the original registration), add <cstdint>, include SKSE/SKSE.h for logging. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VxJjofpgPX8JaNDtgDcZ28
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.
Summary
Investigation into hit zones being misclassified in Special Edition (usually as limbs). The zone math itself is unchanged; this PR hardens the Papyrus-to-native boundary and adds diagnostics so real in-game inputs can be captured.
Classification is byte-for-byte identical to the previous code, verified against the original math over a scenario sweep and 2000 fuzzed inputs.
Changes
GetHitZone. CommonLibSSE turns a None or short Papyrus array into an empty/shortstd::vector; the previousd[5],p[4],s[5]reads were undefined behaviour in that case. Now logs an error and returns 0.traceline is emitted with every input and every threshold. Zone thresholds are independent of one another, so this refactor does not change any result.distnot positive, orasin()producing NaN (dispWidth / dxoutside[-1, 1]). NaN ranges previously fell through to chest/back silently.std::fabsinstead of unqualifiedabson floats. MSVC's ucrt resolves the float overload so the shipped build was fine, but a conforming libstdc++ picksabs(int)and truncates.ArmHitCalcSKSEtakesfloat armRange, matching theLDHitZones.pscdeclaration and the original SKSE64 registration.<cstdint>andSKSE/SKSE.hso it stands alone without the PCH.Findings (not changed in this PR)
dx = xPos - xPosMe(signed world X delta) while the plugin uses it as the denominator inasin(dispWidth / dx). This makes the arm/shoulder tolerance depend on the compass direction of the attack: along world X the tolerance is ~1.5° to 3° (torso hits become arms/shoulders), along world Y it is NaN (hits become chest). Usingp.distinstead would make it geometric. Left as-is pending review since it alters classification.std::vector<float>/std::vector<uint32_t>deduce the same Papyrus signature the SKSE64 build registered, so no marshaling bug was found.Testing
hitDetectionvs. original math, identical on all scenarios and 2000 fuzz cases.plugin.cppsetsflush_on(trace), so the new per-hit trace line flushes to disk on every hit. Fine for debugging; worth lowering before release.🤖 Generated with Claude Code
https://claude.ai/code/session_01VxJjofpgPX8JaNDtgDcZ28
Generated by Claude Code