DARKER Research archive

Angular flight helpers and impact arithmetic

This pass executes original instructions against independent fixed-width arithmetic. It does not yet run a complete flight/collision loop.

Angular response

tools/verify_flight_angular.py checks 600 cases each for entries 83DF, 83D4 and 83BC, plus all 65,536 angles through each of 83A4 and 23A0. The report is angular-verification.json.

The reference in that tool explicitly wraps words and uses signed products. Important reconstruction details:

Input smoothing, complete craft callback behavior, collision response and long trajectories remain separate work. No constants were fitted to observed flight.

Shared object impact

Native impact results cover 144 strength/resistance/damage combinations through CE26, with active object callbacks and nonzero definition resistance. The random angular kick at 854E is intercepted; execution stops before visual effect creation at 6815. Thus this verifies damage and the transition into expiry, not a complete impact.

Let s be the incoming strength byte and r the victim definition byte at +8. For the tested branch, the increment to the object's word at +64 is:

s <= r:       1
r < s < 2*r:  1 + 257 * floor(((s-r)*256 + r) / r)
s >= 2*r:     65536

Overflow of that word selects the death/expiry path. Consequently, a hit no stronger than resistance still adds one; a hit at least twice resistance always overflows. This is a damage accumulator, not a subtraction from conventional HP. The zero-resistance and callback-zero branches are different and are excluded. The upstream strength calculation also varies by weapon.

Separately, the incoming strength accumulates in byte +57; overflow sets the whole +56 word to FFFF. On fatal overflow, +64 becomes FFFF, flag +07 bit 20 is set, and callback +66 becomes 8DAA. The native code also schedules +68 from the current clock and overflow-related arithmetic. Handling an object already awaiting expiry remains outside these fixtures. The later list removal and mission counter behavior is covered by object completion. These findings must not be treated as the player's scenery-crash rules.

Building state mutation

The small native span 67C1–67D5 was tested for all 256 incoming state bytes. It adds 20h with byte wrap, then increments counter C221 if the resulting state has bit 7 set. It neither ORs in a destruction bit nor saturates the state. The type byte remains unchanged.

This is only the mutation after a caller has admitted a hit. It does not prove that every building can be destroyed, that repeat hits always reach this code, or that aircraft collisions use it. In particular, the observation that lamppost crashes show a destroyed model remains to be connected to the actual player collision path. The existing alternate-state asset links alone cannot answer that question.

Reproduction

PYTHONPATH=/tmp/darker-python python3 tools/verify_flight_angular.py
PYTHONPATH=/tmp/darker-python python3 tools/verify_impact_damage.py

Follow-up: player collision and damage now verifies the streetlight-specific crash mutation, controlled native geometric sweeps, and the exact limits of the player damage cheat. Earlier open questions on that response path are superseded by these tests.