Feat roads#36
Closed
El-Magico777 wants to merge 8 commits into
Closed
Conversation
This commit introduces a comprehensive road network and an accompanying cargo truck economic system, adding a new layer of strategic depth to the game. Players can purchase the "Roads" upgrade to build a network between their structures. Once connected, cargo trucks automatically travel these routes, generating passive income and rewarding well-planned infrastructure. ### Core Components & Architecture - `RoadManager` & `StructureGraph`: At the heart of the system, RoadManager.ts orchestrates road creation and pathfinding. It replaces a previous batched implementation with a more robust StructureGraph.ts, which maintains a real-time graph of all player structures (Cities, Ports, etc.) and the road paths connecting them. This allows for efficient pathfinding and connectivity checks. - `CargoManager` & `CargoTruck`: A new CargoManager.ts is introduced to handle the economic aspect. It periodically finds paths between a player's economic structures using the StructureGraph and spawns CargoTruck units. These trucks travel the road network and, upon reaching their destination, award the player gold based on the travel distance. - AI Integration: Bot behavior in FakeHumanExecution.ts has been enhanced. AI players can now purchase the road network upgrade and will intelligently build roads to connect their structures, allowing them to participate in the new economic loop. ### Pathfinding & Logic Enhancements - A* Cost-Based Pathfinding: The A* algorithm in RoadManager is now weighted. The cost for traversing existing road tiles is 1, while new land tiles cost 2. This incentivizes the pathfinder to build new, efficient shortcuts rather than creating long, winding roads that follow existing paths. - "5-Hop" Redundancy Check: To prevent wasteful spending, the system performs a "5-hop" check on the StructureGraph before building a new road. A new road is only built if no alternative path of 5 or fewer segments already exists, preventing the creation of inefficient, redundant roads (e.g., small triangles). - Stable Construction Connections: Roads no longer connect to "Under Construction" sites. They now only link to fully built structures, which resolves a significant visual bug where roads would flicker or disappear upon a building's completion. ### UI, Rendering & Performance - `RoadLayer` & `CargoTruckLayer`: Two new rendering layers have been added. RoadLayer.ts is responsible for drawing the road network on the canvas, with logic to style roads based on ownership. CargoTruckLayer.ts renders the individual cargo trucks moving along the paths. - `RoadCache` & `OffscreenCanvas`: To optimize rendering performance, RoadCache.ts uses the OffscreenCanvas API to cache road segment visuals, reducing the need to redraw static road segments each frame. - UI Integration: The research tab in ControlPanel2.ts now includes the option for players to purchase the "Roads" upgrade, which is the entry point for this entire feature. ### Configuration & Testing - `DefaultConfig.ts`: New configuration options have been added for the road upgrade cost, road updates per tick, and cargo truck income scaling. - Test Suite Fix: A mock for OffscreenCanvas was added in tests/setup.ts and enabled in jest.config.ts. This resolves test failures in the Node.js environment where this browser-only API is not available.
Refactors the research tab UI to improve usability and prepare for future upgrades. - Replaces the single research column with a tabbed interface for Land, Water, Air, and Economy categories. - Moves the tabs to the bottom of the panel for better ergonomics and a cleaner look. - Styles the tabs to give them a more distinct, physical appearance with borders and shadows. - Implements a tiered cost system for upgrades (1M, 2M, 3M). - Upgrade costs are now set to zero in single-player mode with the "unlimited money" setting enabled. - All placeholder upgrade buttons are now rendered as "live" and will correctly disable based on cost and player funds.
Improves performance in hot paths by reusing typed array views for GameMap.neighbors, significantly reducing heap churn and garbage collection pressure during frequent neighbor lookups (e.g., in pathfinding). - Returns a Uint32Array view instead of allocating new arrays on each call. - Adds a small buffer pool to avoid data being overwritten during nested calls. - Updates the GameMap interface and its implementations (GameImpl/GameView) to return Uint32Array. - Adapts GraphAdapter.neighbors to return an Iterable to maintain compatibility. - Existing call sites remain valid as typed arrays support standard iteration protocols.
This commit introduces a new mechanic where roads influence attack pathfinding, providing a strategic advantage for offensive maneuvers. - Attack Pathfinding Priority: The priority calculation for conquering neighboring tiles in AttackExecution.ts is modified. Tiles with roads are now prioritized (bonus of +10), incentivizing attacks to follow the road network. - Core Integration: To support this, a hasRoadOnTile method was added to the Game interface and its implementations. This method efficiently checks if a given tile has a road, enabling the priority calculation. This change makes roads a factor in combat by guiding attacks along the network, facilitating faster territorial expansion.
Introduces a comprehensive update to the trade system by formally distinguishing between domestic and international cargo trucks. This provides a richer economic layer for alliances,
improves performance, and lays the groundwork for future mechanics like embargoes.
This commit combines the implementation of international trade convoys with performance and internationalization enhancements.
### Key Enhancements & Player-Facing Changes
#### 1. International Trade Convoys (Alliance-Based Economy)
A new trade mechanic allowing players in an alliance to generate gold by sending cargo trucks to one another, creating a direct economic incentive for cooperation.
- Economic Alliances: Being in an alliance is now more profitable than ever. Special international cargo trucks will automatically spawn and travel between you and your allies'
cities.
- Shared Profits: When a convoy reaches its destination, both you and your ally receive a large gold bonus, with the split ratio being configurable.
- New Visuals: International trucks are rendered as a distinct two-block unit, providing a clear visual distinction from domestic trucks.
- New Strategy: Protect your trade routes and connect your road networks to your allies to maximize your shared income.
#### 2. Performance and User Experience
- Domestic Trade Aggregation: Gold received from domestic cargo trucks is now aggregated, and a single summary message is sent every 30 seconds. This significantly reduces message
spam and improves both server and client performance, especially in the late game.
- Internationalization (i18n): All new player-facing messages for both international and domestic trade have been implemented with translation keys, improving the game's localization.
### Technical Implementation Details
- Configuration (`Config.ts`, `DefaultConfig.ts`):
- Adds internationalCargoTrucksEnabled, internationalCargoTruckSpawnChance, internationalCargoTruckGoldMultiplier, and internationalCargoTruckGoldSplitRatio to the core
configuration, allowing server operators to tune or disable the feature.
- Core Logic (`CargoManager.ts`):
- Spawning: Spawning logic is distributed across multiple ticks using a player bucketing system to avoid CPU spikes. Expensive lookups for trading partners are deferred until after
a spawn chance passes to optimize performance.
- Arrival Validation: A hardened arrival check validates that players can still trade (canTrade()) and are alive before distributing gold, preventing exploits from broken alliances
or defeated players.
- Type Safety: Gold calculations correctly handle bigint and number multiplication to ensure type safety.
- Serialization (`GameUpdates.ts`):
- The SerializedCargoTruck interface is extended with optional isInternational and destinationOwnerID properties. This ensures new data is passed to the client without breaking the
existing structure of update payloads.
- Client-Side Rendering (`CargoTruckLayer.ts`):
- The rendering logic is updated to draw international trucks as a two-block unit by drawing the lead block at the truck's current position and a "trailer" block at its previous
position in the path array.
This commit refactors the international trade system by making it a strategic, purchasable upgrade. Previously, this feature was a default capability for all players. Now, it must be unlocked via the Research tab to enable international trade routes. ### Change Breakdown: - **Core Feature Definition (`Game.ts`, `DefaultConfig.ts`):** The placeholder `LandUpgrade2` enum has been renamed to the descriptive `InternationalTrade`. The corresponding configuration was updated to ensure the upgrade's cost is correctly applied. - **Gating Mechanism (`CargoManager.ts`):** The core logic is implemented here. The spawning of international trucks is now gated by a check to ensure the player has purchased the `InternationalTrade` upgrade. This makes international trade a deliberate choice. - **UI Implementation (`ControlPanel2.ts`):** The Research tab UI now displays the "International Trade" button, allowing players to purchase the upgrade. A minor visual bug was also fixed to properly center the button's text and icon. - **Bot Integration (`FakeHumanExecution.ts`):** To ensure game balance and consistent behavior, FakeHuman bots are now granted the `InternationalTrade` upgrade for free upon initialization. This allows them to participate in the new system without requiring complex purchasing logic. - **Performance Optimization (`PurchaseUpgradeExecution.ts`):** The execution logic for all upgrade purchases has been refactored to be instantaneous (moved from `tick()` to `init()`). This is a performance improvement that reduces server overhead by processing purchases immediately.
…twork This commit introduces the new 'Scorched Earth' strategic upgrade. This feature allows a player to destroy their entire road network, providing a powerful strategic option to reset infrastructure. The implementation is designed to be performant and visually instantaneous. - **New 'Scorched Earth' Upgrade:** Players who have researched Roads can now access a powerful, repeatable strategic option. Purchasing 'Scorched Earth' will instantly destroy your entire road network. - **Repeatable Cycle:** After use, the 'Roads' upgrade is also removed. A player must re-purchase the 'Roads' upgrade before they can purchase and activate 'Scorched Earth' again. - **UI Improvement:** A tooltip has been added to the 'Scorched Earth' button, clearly stating "This upgrade will remove your road network" to prevent accidental activation. The implementation is designed for high performance and immediate visual consistency. - **Configuration:** `UpgradeType.LandUpgrade3` was renamed to `ScorchedEarth` and its cost was defined in `DefaultConfig.ts`. - **Core Logic (Purchase-to-Use):** - `PurchaseUpgradeExecution.ts` handles the 'Scorched Earth' type. The purchase of the upgrade serves as the trigger for the action. - Upon purchase, the code immediately calls `game.destroyPlayerRoads()`, then removes both the `Roads` and `ScorchedEarth` upgrades from the player. This consumption of the upgrade allows it to be purchased again later, creating a repeatable cycle. - The `Game` and `Player` interfaces were extended with methods like `destroyPlayerRoads` and `removeUpgrade` to support this. - **Performant & Visually Consistent Road Destruction:** - A new `removeEdge()` method was added to `StructureGraph.ts` to allow for the efficient removal of a single road from the abstract graph. - The `RoadManager.ts:destroyPlayerRoads` method uses this new function. It iterates only through the roads owned by the player (`O(R)` complexity) and surgically removes each one from all necessary caches (including `existingRoadSegments` to prevent issues with road reformation) and the `StructureGraph`. - The `RoadManager.update()` method is structured to guarantee that pending visual changes (like road removals) are processed and returned on every tick, even if no players currently have the `Roads` upgrade. This ensures the visual effect of `Scorched Earth` is always instantaneous. - **UI Polish:** - `ControlPanel2.ts` was modified to render the button, including a new `title` attribute for a tooltip, which is passed in from the `renderUpgradeButton` function.
Introduces new test suites to improve coverage and validate the functionality of the CargoManager, RoadManager, and the PurchaseUpgradeExecution. - `tests/core/game/CargoManager.test.ts`: Verifies the spawning, movement, and completion of domestic cargo trucks, and the generation of trade summaries. - `tests/core/game/RoadManager.test.ts`: Ensures correct road formation, dependency on the 'Roads' upgrade, and proper handling of road destruction and reconnection. - `tests/client/layers/RoadLayer.test.ts`: Confirms that the client-side RoadLayer correctly responds to road updates for rendering. - `tests/core/execution/PurchaseUpgradeExecution.test.ts`: Validates the logic for purchasing upgrades, including fund checks and specific side effects for 'Scorched Earth' and 'Roads' upgrades. - `tests/integrations/ScorchedEarth.test.ts`: An end-to-end integration test simulating the full lifecycle of road network destruction and rebuilding via the 'Scorched Earth' and 'Roads' upgrades. These tests enhance the robustness and reliability of the game's core mechanics.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description:
Describe the PR.
Please complete the following:
Please put your Discord username so you can be contacted if a bug or regression is found:
DISCORD_USERNAME