# Persistent cell-state fields: first native check

BB90 serializes two state bits per eligible map cell. BBC6 restores them before regenerating low variant bits at BBFC. Four controlled original-code pack/restore cases establish that ordinary cells preserve **20h and 40h**: low variant bits and high bit 80h are not copied by this ordinary packed representation.

Eligibility is determined by the runtime type descriptor at A004 + type*8: descriptor byte FF excludes a cell from this stream. The fixture uses included type 2 and excluded empty type 0. It does not assume every building or beacon is eligible.

The writer is invoked through BC2D from the successful progression path near 3F0A. BC2D selects a state area at saved-record +22h for mode 0, or +3DBh for mode 1, and declines this serialization for modes above 1. Therefore this path supports separate main-city/Halon state streams; it does not establish tunnel persistence through the same mechanism.

This is evidence that selected building-state bits can survive progression, not yet a complete repair policy. BBC6 also has a separate treatment for templates with state bit 80h; that branch and the later variant-index rebuilding are outside this check. Determining which real bank definitions are included, when the saved stream is reset, and whether particular mission damage is repaired remains necessary.

Run `PYTHONPATH=/tmp/darker-python python3 tools/verify_persistent_cell_state.py`. [Results](../analysis/missions/persistent-cell-verification.json) record source bytes, packed byte and restored fields. Source patterns include high and low bits to show which bits survive. The fixture does not exercise disk save I/O or the complete mission transition.

## Real bank/map verification

The [eligibility viewer](../analysis/missions/persistent-state.html) now shows included/excluded cells and allows type selection. [persistent-map-state.json](../analysis/missions/persistent-map-state.json) exports all type IDs, per-map counts and native verification results.

| City | Eligible cells | Packed bytes | Save-record offset |
|---|---:|---:|---|
| Delphi, map 68 / bank 30 | 3,811 | 953 (03B9h) | +0022h |
| Halon, map 69 / bank 31 | 1,870 | 468 (01D4h) | +03DBh |

The Halon start is exactly `0022h + 03B9h`, independently matching Delphi's measured packed stream length. Ordinary saved damage bits are restored for both cities; this is not a distinction where only Halon has a persistence stream.

Bank 30 excludes types 18,20,22,24; 39–43; and 106–119. Bank 31 excludes 8–23. Every other declared type in those banks is eligible, including Delphi streetlights (11), warehouse roof/interior types (75–77), offices (86–89), energy towers (1), and Halon supply pads (3). Inclusion means a cell participates in serialization, not necessarily that all damage stages have meaningful models for that type.

All 174 bank-32 descriptors are eligible at the codec level, but the normal selector bypasses mode 2. The eight tunnel maps were therefore tested as codec inputs only; this must not be described as proof they are saved during ordinary progression.

The native test serializes synthetic state patterns on all ten **real** maps using their real bank descriptors, restores them, then executes the low-variant rebuilding at BBFC. Every cell is checked. Per-type variant counters restart from zero and cycle according to descriptor byte +6, so low state bits are regenerated rather than preserved from the source state.

## Energy towers and high-bit templates

A restored cell whose fresh template already has bit 80h takes BC27 instead of the ordinary path. The saved two-bit code restores as **00h if zero, FFh otherwise**. Main-city map initialization makes its 225 lattice type-1 cells FF, so they take this special path.

As a result, save/restore preserves tower state as binary off/full rather than a fractional fade strength. The codec stores `(state >> 5) & 3`, not a dedicated `state != 0` boolean, so arbitrary intermediate source values can quantize unexpectedly; the normal exit path's queued-outage commit and completed fades help explain why stable endpoints matter. The tests verify the original operation rather than smoothing or normalizing it.

This high-bit handling describes the fresh restore template. It must not be confused with the source state's 80h alternate-model bit, which is not stored independently.

## Mission-exit connection

[Native exit checks](mission-exit-state.md) now execute the queued-outage commit and the branch that writes the city state stream. Full next-mission loading, disk save formats and repair/reset paths beyond these routines remain separate.

Run `PYTHONPATH=/tmp/darker-python python3 tools/inspect_persistent_map_state.py` for the complete real-map checks and viewer.

## Failure and reload follow-up

[Native real-slot exit/reload chains](city-retry-and-selection.md) now confirm that tested failure outcomes retain the earlier committed stream while successful progression saves new damage. Stage byte 1 bypasses restoration. These checks use original city resources and actual slot lookup; outer menu and disk I/O remain separate.
