Show rail ghost for initial factory 🚂#4294
Conversation
Building a factory with no pre-existing factory nearby (e.g. just a city) showed no rail ghost, even though building it would lay rails to that city. computeGhostRailPaths required a nearby Factory and only matched neighbors that were already train stations. But a Factory always becomes a station and promotes nearby City/Port/Factory into the network itself, so it needs no pre-existing factory and should connect to structures that aren't stations yet. City/Port keep requiring a nearby factory (they only join when one exists). Fixes #4284 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Walkthrough
ChangesFactory Ghost Rail Path Fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed due to a network error. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/core/game/RailNetwork.test.ts (1)
380-409: ⚡ Quick winUse the test
setup()helper for these new rail preview cases.These new tests build the game with local mocks and private
(network as any)access. The repo guideline asks tests undertests/**to usetests/util/Setup.tsand exercise core simulation directly, so please rewrite these cases aroundsetup()and real game placement/build-preview behavior instead of mockingRailNetworkImplinternals.As per coding guidelines, "
tests/**/*.test.ts: Use thesetup()helper fromtests/util/Setup.tsto create test game instances and exercise core simulation directly."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/core/game/RailNetwork.test.ts` around lines 380 - 409, Refactor the test cases "factory connects to nearby structures with no pre-existing factory" and "city does not connect to non-station neighbors without a factory" to use the setup() helper from tests/util/Setup.ts instead of mocking RailNetworkImpl internals. Replace the local vi.fn() mocks and private (network as any) access patterns with real game instances created via setup(), and exercise the computeGhostRailPaths method by setting up actual game state (placing units, stations, and cities) rather than mocking game.hasUnitNearby, game.nearbyUnits, stationManager.findStation, pathService.findTilePath, and railGrid. This aligns with the repo guideline that tests under tests/** should use setup() and test core simulation behavior directly.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/core/game/RailNetwork.test.ts`:
- Around line 380-409: Refactor the test cases "factory connects to nearby
structures with no pre-existing factory" and "city does not connect to
non-station neighbors without a factory" to use the setup() helper from
tests/util/Setup.ts instead of mocking RailNetworkImpl internals. Replace the
local vi.fn() mocks and private (network as any) access patterns with real game
instances created via setup(), and exercise the computeGhostRailPaths method by
setting up actual game state (placing units, stations, and cities) rather than
mocking game.hasUnitNearby, game.nearbyUnits, stationManager.findStation,
pathService.findTilePath, and railGrid. This aligns with the repo guideline that
tests under tests/** should use setup() and test core simulation behavior
directly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ad25d3d0-b15b-45c3-b413-60582ede7d9e
📒 Files selected for processing (2)
src/core/game/RailNetworkImpl.tstests/core/game/RailNetwork.test.ts
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
computeGhostRailPathsinRailNetworkImpl.tshad two factory-hostile assumptions:Factorywas already in range (hasUnitNearby(..., UnitType.Factory)).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
Factory.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