# Object completion and mission objective counters

The native 79BB list walker processes expired lifecycle states before the player's mission interpreter runs. At 7A52–7A82, object +46 bit 0 determines whether completion increments C21B and decrements outstanding counter C16F. C16E clamps a negative signed result to zero.

The remaining bits of +46 control the disposition:

- Zero upper bits: unlink the expired object through 7AB4, without adding it to the free list.
- Upper bits 02h or higher below FEh: subtract two and recycle through 1CD4; the updated byte no longer retains the counted-object bit.
- Upper bits FEh: recycle without that decrement.

1CD4 prepends to header +4 and repairs active head/tail and neighbour links. Both removal paths return the next active object to the walker, allowing several expirations in the same pass. These are lifecycle effects, not a claim that every expiry corresponds to a player kill.

`tools/verify_object_completion.py` checks six two-object fixtures: counted/uncounted objects crossed with lifecycle upper bits 00h, 02h and FEh. It runs the original list walker, counter writes, list removal/recycling and then the player interpreter. With the objective cell list exhausted, both counted expirations reduce the outstanding count to zero, and the player's wait passes **in the same update**, scheduling its next delay.

[Results](../analysis/missions/object-completion-verification.json) retain free-list heads, completed counts and player continuation deadlines. Objects are supplied already expired; combat damage, collision and creation of the expired state are not simulated. This closes one scheduling link between object lifecycle and mission progression, not the entire mission lifecycle.
