Merged PRs — Halcyon Reach, weeks 2–4#

52 PRs merged since the first post (#120 → #184).

Combat & ships (11)

  • #184 feat(anomaly): wave-based PvE encounter (Hidden Outpost) + HUD
  • #173 feat(combat): friendly-fire gate + rep aura for Healer reps
  • #170 feat(salvage): scrap loot tables on ship death + wreck fragments
  • #167 feat(ai): four archetypes (brawler / sniper / healer / EWAR)
  • #138 3 MVP hulls: Mauler, Reach (+skillshot substrate), Bulwark
  • #135 feat: Cipher Frigate (Swap) + TargetedSwap EffectKind
  • #134 refactor(client): uniform hull-ability cooldown + predicted-vs-not press
  • #133 feat: Drift Cruiser (Lasso) + ForcedMovement substrate
  • #132 content(hull): Lance Frigate — MVP frigate Sniper
  • #131 Mend Frigate: hull + Surge + ship picker + data-driven ability bar
  • #130 Stat::DamageTaken + the primitive-shape gate (handoff PR-A)

World & zones (9)

  • #179 feat(stations): undock invuln + dock animation + combat-log gate
  • #171 feat(world): buildings as catalog-driven entities + interior overlay
  • #165 feat(world): 3-sector triangle + arena as runtime-spawned instance
  • #163 feat: Sector isolation + gate-by-id + Region map / Sector label
  • #162 feat(zone): Sector isolation + gate handoff (keystone)
  • #161 feat(render): procedural nebula background
  • #160 refactor(render): world rendering through a SubViewport
  • #123 feat(arena): EVE-style gate warp into a separate pocket
  • #122 feat(arena): server-side battle spawn — two NPC teams fight to a winner

HUD / UI (12)

  • #174 feat(ui): wire main-menu Quit to Desktop with logout confirmation
  • #169 feat(ui): tabbed settings panel with display mode + resolution
  • #168 feat(minimap): Ctrl+wheel zoom + bottom-right stepper
  • #157 fix(hud): rip the 'gate' substring filter (caught every _frigate)
  • #142 feat(hud): connection status chip + release.yml tarball fix
  • #140 feat(tooltip): icon in header, left of title
  • #139 feat(catalog): printf-style tooltips from canonical JSON
  • #137 feat(hud): Overview rail — persistent sensor briefing
  • #136 fix(lock): shared lock-time formula + lock-range gate + ATTACK/LOCK ring labels
  • #127 Unify target HUD onto shared tokens + laptop-capable zoom
  • #121 Arena UI + Catalog; fix client reconciliation (missing PredictionManager) + predicted stop
  • #120 feat(ui): HUD redesign — ability bar + vitals panel

Networking & identity (4)

  • #159 feat(identity): per-pilot display name end-to-end
  • #155 feat(connect): pre-game lobby with version handshake gating
  • #153 fix(net): per-install client_id (NAT collision was actually identity collision)
  • #147 fix(net): auto-reconnect actually reconnects after the server restarts

Release / infra / build (8)

  • #152 fix(release.yml): use 7z on Windows runners (real zip, not a tar)
  • #150 chore(release-skill): bump Cargo.toml before stable tag
  • #149 feat(version): bake build tag, surface in HUD
  • #148 chore(release.yml): auto-publish releases
  • #146 feat(dev.sh): remote area — restart the droplet without a redeploy
  • #145 chore(release.yml): drop macOS server build
  • #143 feat(release): rc-tag gate + /release skill for server-only deploys
  • #125 feat(protocol): codegen GDScript wire-tag constants from the Rust registry

Refactors / architecture (3)

  • #166 refactor(godot-client): split lib.rs into per-concern modules
  • #129 Data-driven content: kill central registries so content is parallelizable
  • #128 refactor(ship): decompose ship.gd into layered systems + visual child

Chores / docs / tests (5)

  • #180 chore: tighten verbose comment blocks across the codebase
  • #172 test(zone): cover apply_set_active_target / keep_at_range / reset_npcs + lock-range gate
  • #164 chore(comments): strip historical narration
  • #126 docs: soften PR-splitting rule, mark design as evolving
  • #124 chore(art): add fetch_lucide.py — vendor Lucide temp UI icons