DARKER Research archive

Player collisions, streetlight destruction and shields

Why a crashed-into streetlight changes model

The observation is supported by the original response path and real bank collision data: Delphi type 11 is the only base-state type in banks 30–32 with a collision primitive that qualifies for building damage from the player handler. Other player building impacts still crash the player, but do not advance the building state through this handler.

The player list header is 6FD0. Collision dispatch at 6E56 selects a word at list header +28, with result-category bits added to the header address:

Outcome Player handler
Terrain/surface 6F84
Map building 6EEC
Other object 6ED4

6EEC first skips a player already carrying expiry flag 20. Otherwise it calls CDB9, then enters the player crash sequence at 6F4F. CDB9 resolves the current model through 2DE1, including state-selected alternate/damage links. For a player definition, category 2 and a nonzero current model damage link admit mutation at 67C1. Category 1 is excluded; other categories reach weapon checks which player definition pointers do not pass.

The category is not the building type ID or the descriptor's collision marker. It comes from a collision primitive's opcode shifted right by three (606C–6073). Type 11's base collision stream begins at 8080 with opcode 10, giving category 2. The native model selection and admitted-hit response were checked for states 00, 20, 40, 80, across the four player definitions 25–28. The resulting 5,088 cases all passed. At base state, the eligible set is {11} for Delphi and empty for Halon and the underground bank.

These tests use actual model headers and collision streams but supply the hit category from those streams. They do not execute geometric intersection or prove a collision from every approach. Types marked non-colliding (FF in the bank descriptor) are excluded. Visual effect spawning is intercepted after native state mutation; the player crash state changes execute normally.

Crash transition

6F4F installs motion callback 6EF7, marks flags 08 and 20, and schedules expiry 1,536 clock ticks after BF8 (approximately 3.07 seconds at 500 Hz). It clears speed +3E, engine/shield flag 4552, and other control/camera state. The crash motion callback changes heading and steers pitch toward EC00. This is a separate lethal path from ordinary damage accumulation.

The terrain handler 6F84 additionally ignores contact while object flag 10 is set; this is consistent with a special landing/docking state, but not yet a complete explanation of all terrain contacts. The object-collision handler 6ED4 damages the other object with strength 5C, then applies randomized player damage with its high bit set. Neither path is included in the building census fixture.

Reproduction

PYTHONPATH=/tmp/darker-python python3 tools/verify_player_collisions.py

Native results and collision-category census.

Geometric confirmation

A second fixture now runs 6DF1, 6D35, 6527 and the native collision primitive tests, rather than supplying an admitted hit. It sweeps the player through isolated real Delphi models along both horizontal axes and directions, at six heights, in base and first-damage states. 384 sweeps produced 256 building hits and 20 building-state changes. The tested types are 1, 11, 12, 30, 75, 76, 77 and 86; every state change was a streetlight.

For a concrete comparison, a horizontal centre crossing at height 100 collides with both type 11 and type 30. The streetlight advances from state 0 to 32; the house stays at state 0; both crash the player. The same streetlight crossing at height 1000 clears the geometry. Impact coordinates are recorded too.

This closes the geometry-to-response link for controlled trajectories. The old and new positions are supplied, not produced by a flight callback; other objects and effects are excluded. It is not a captured gameplay run.

PYTHONPATH=/tmp/darker-python python3 tools/verify_player_collision_geometry.py

Geometric sweep results.

Player damage and the invulnerability cheat

A further 20,480 native cases execute 84D0 (including its randomized angular kick) and the health/crash gate 6F45. They cover every incoming damage byte, Caero and both Skimmas, shields enabled/disabled, several reserve levels and initial Caero damage levels, with and without “Who gives true life?”. Visual effect spawning alone is intercepted.

The Caero damage word at 8509 has a peripheral amount in its low byte and a major-damage count in its high byte. Every 68 peripheral units become one major unit. An incoming byte with bit 7 set contributes two major units plus its lower seven bits. A high-byte count of at least four causes the crash gate to fire. This agrees with the manual's outer/inner Damage Report System display, rather than treating its two indicators as unrelated quantities.

For Skimmas, an enabled shield subtracts the incoming byte from reserve 810A. Depleting it exactly is lethal, as is exceeding it: status high byte becomes 4, which the subsequent gate turns into a crash. With shields disabled, any call through this damage path sets that lethal status. This includes a zero incoming value; whether such an event occurs naturally depends on the caller.

The cheat zeroes incoming AL after the angular kick. It prevents new Caero damage here and preserves a positive enabled Skimma shield reserve. It does not prevent the unshielded Skimma branch or the zero-reserve branch from marking lethal damage, remove pre-existing lethal Caero damage, or bypass the separate building-crash handler. Nor does it suppress the preceding impact kick. Thus it is not universal invulnerability.

PYTHONPATH=/tmp/darker-python python3 tools/verify_player_damage.py

Player damage results.

Flight callback integration

The interactive native trace viewer replays 48 controlled runs. Each step executes the entire normal Caero 7EB6 or Skimma 8108 callback, then native collision pass 6F0F. Craft definition motion parameters and the vertical displacement patch come from the original records; the sine-table startup extension is included. Both engine/shield states and cheat states are covered. Twenty-eight runs enter the crash callback; the rest reach the 512-tick limit, which does not imply they are indefinitely safe.

The cheat leaves each paired scenery trace identical. All building-state changes are streetlights. These runs use fixed 8-tick steps, zero processed input, an isolated building and a supplied airborne initial state; no claim is made of complete game-loop or independent C++/Python flight-model equivalence. Full flight instructions execute, but input production, other actors, drawing and effect spawning are excluded. Upgraded Skimma starts after its initial docking transition. Reproduce with tools/trace_flight_collision.py.