Files
Evan 83cd864018 Show rail ghost for initial factory 🚂 (#4294)
## Problem

Fixes #4284. When you build a factory in an area with **no pre-existing
factory** (e.g. just a city nearby), no rail ghost preview appeared —
even though building the factory *would* lay rail lines connecting it to
that city.

## Root cause

`computeGhostRailPaths` in `RailNetworkImpl.ts` had two factory-hostile
assumptions:

1. It bailed out early unless a `Factory` was already in range
(`hasUnitNearby(..., UnitType.Factory)`).
2. It only matched neighbors that were *already* train stations
(`findStation(...)` → skipped if null).

But a **Factory** always becomes a station itself and *promotes* nearby
City/Port/Factory into the rail network (see `FactoryExecution`). So it
needs no pre-existing factory, and its neighbors won't be stations yet
on first build. A **City/Port** only joins the network when a factory
already exists (`CityExecution`/`PortExecution`) — so their behavior is
correctly left unchanged.

## Fix

- Skip the "factory must be nearby" gate when the placed unit is itself
a `Factory`.
- For a factory build, pathfind to nearby City/Port/Factory even if they
aren't stations yet. City/Port keep connecting only to existing
stations.

## Tests

Added two cases to `RailNetwork.test.ts` (factory connects with no
pre-existing factory; city still doesn't without one). All 25 tests
pass.

## Note on scope

As @Katokoda noted on the issue, a fully build-exact preview
(neighboring structures also connecting to *each other*, merging
existing networks, etc.) is larger and order-dependent. This PR resolves
the reported bug — the initial factory now shows its rail ghost — and
leaves the exact-match cascade as a separate follow-up.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 08:22:01 -07:00
..