Research Tree UI Overhaul and Enhancements#74
Closed
El-Magico777 wants to merge 38 commits into
Closed
Conversation
…omation upgrades
This commit introduces three new upgrades to the economy tech tree, providing players with new strategic options for economic development.
### Implemented Upgrades
1. **Urban Planning:**
- Increases the maximum population capacity by 25%.
- This allows for greater population growth and a larger potential workforce and army.
2. **Structure Insurance:**
- Provides a 33% refund of a structure's original cost when it is destroyed by an enemy or captured.
- The refund is credited to the original owner of the structure.
- This helps players recover from losses and rebuild their infrastructure more quickly.
3. **Automation:**
- Doubles the gold generated from domestic trade routes (100% increase).
- Reduces the rate of troop regeneration by 20%.
- This upgrade offers a trade-off between economic growth and military reinforcement speed.
### Technical Details
- **Configuration:** Added new configuration options in `Config.ts` and `DefaultConfig.ts` to manage the parameters of the new upgrades.
- **Game Logic:**
- Implemented the population bonus in the `maxPopulation` function.
- Added refund logic to the `delete` and `setOwner` methods in `UnitImpl.ts`.
- Integrated the trade bonus into the `CargoManager.ts`.
- Updated the troop regeneration formula in `DefaultConfig.ts`.
- **UI:** Added new message types and a "Financial" event category to inform players of insurance refunds.
- **Testing:**
- Created a new test file `EconomyTechEffects.test.ts` with comprehensive tests for each new upgrade to ensure they function as expected.
- Updated existing tests to incorporate the new upgrades.
This commit introduces the Submarine, a new strategic naval unit available after purchasing the 'Submarine' research item from the 'Water' research tab. The Submarine functions as a stealth-based ship-killer.
Its core mechanic is visibility:
- By default, it is invisible to enemy players.
- It is revealed to enemies under three conditions:
1. For 3 seconds every 15 seconds (the 'periodic ping').
2. For the entire duration that it is actively attacking a target.
3. As long as it is within the weapon range of a threatening enemy naval unit (Warships and other Submarines).
Unlike the Warship, the Submarine destroys all targets, including enemy Trade Ships, which it does not capture. For this initial implementation, the Submarine uses the Warship's graphics as a placeholder.
This feature was implemented by touching on all layers of the application, from core game logic to the client-side UI, ensuring adherence to existing architectural patterns.
- **`src/core/game/Game.ts`**: Added `UnitType.Submarine` and `UpgradeType.SubmarineResearch` to the core enums. The `Unit` interface was extended with optional properties (`isDetectedByNavalUnit`, `isAttacking`, `lastVisibleTick`) to manage the new stealth state.
- **`src/core/configuration/DefaultConfig.ts`**: Defined the base stats, build cost, and research cost for the Submarine and its corresponding upgrade, ensuring they are configurable.
- **`src/core/execution/SubmarineExecution.ts`**: This new file contains the core AI for the unit, created by adapting `WarshipExecution.ts`. Key changes include:
- Removing the `huntDownTradeShip` method to ensure Trade Ships are attacked, not captured.
- Adding an `updateDetectionState` method, which runs every tick to check for nearby enemy naval units (`Warship` or `Submarine`) and updates the unit's `isDetectedByNavalUnit` state.
- Setting the `isAttacking` flag to true only when the submarine is actively firing.
- **`src/core/execution/ConstructionExecution.ts`**: Modified the `completeConstruction` switch statement. A case for `UnitType.Submarine` was added to ensure a `SubmarineExecution` instance is created and added to the game loop when a submarine is finished building.
- **Stealth & Visibility System**:
- **`src/core/game/GameUpdates.ts`**: A new `SubmarinePing` update type was added to the `GameUpdateType` enum and `GameUpdate` union to communicate visibility events to the client.
- **`src/core/GameRunner.ts`**: The main game loop in `executeNextTick` was modified to include the server-side periodic ping logic. It iterates through submarines and fires the `SubmarinePing` update every 15 seconds.
- **`src/core/game/GameView.ts`**: The client-side `GameView` was updated to process these `SubmarinePing` updates, storing the last ping time. A new `isUnitPeriodicallyVisible()` method was added.
- **`src/client/graphics/layers/UnitLayer.ts`**: The `onUnitEvent` method was modified with a crucial check that prevents the submarine from being rendered for non-owners unless one of the three visibility conditions (periodic ping, attacking, or detected) is met.
- **UI & Control**:
- **`src/client/graphics/layers/ControlPanel2.ts`**: The `render` method was updated to include a `renderUpgradeButton` call for `UpgradeType.SubmarineResearch` in the 'Water' tab. The `AttackTypes` array was also updated to include `UnitType.Submarine`.
- **`src/client/graphics/layers/BuildMenu.ts`**: The `recomputeFilteredTable` method was modified to filter the submarine build button from the menu unless the player `hasUpgrade(UpgradeType.SubmarineResearch)`.
- **`src/core/Schemas.ts` & `src/client/Transport.ts`**: To support patrol movement, a new `move_submarine` intent was defined, and the necessary `MoveSubmarineIntentEvent` and handlers were added to the client transport layer.
- **Asset Loading (`src/client/graphics/SpriteLoader.ts`)**: The `SPRITE_CONFIG` map was updated to associate `UnitType.Submarine` with the `warshipSprite`, preventing a runtime error and providing a placeholder graphic.
- **Testing (`tests/Submarine.test.ts`)**: A new test suite was created by adapting `Warship.test.ts`. The test for trade ship interaction was updated to assert destruction instead of capture.
This commit updates the bot AI to utilize the new Submarine unit, bringing their strategic capabilities in line with recent naval additions.
1. **Granted Submarine Research by Default:**
- Bots (specifically the `FakeHumanExecution` type) are now granted `UpgradeType.SubmarineResearch` upon initialization.
- This ensures that bots have the prerequisite upgrade needed to build Submarines from the start of a game.
2. **Implemented 50/50 Naval Spawn Strategy:**
- The unit creation logic for bots in `UnitCreationHelper` has been updated.
- When a bot decides to build its first naval combat unit, it now has a 50% chance to build a `Submarine` and a 50% chance to build a `Warship`.
- This was achieved by refactoring the previous `maybeSpawnWarship` method into a more generic `maybeSpawnNavalUnit` method that handles the random selection and construction of either unit type.
This commit adds the missing client-side UI logic to allow players to select and control submarines. - In `UnitLayer.ts`, added logic to detect clicks on submarines and to emit the `MoveSubmarineIntentEvent` when a move order is given. - In `UILayer.ts`, updated the rendering conditions to ensure the selection box is drawn around a selected submarine. This brings the submarine's UI interaction in line with the Warship and Fighter Jet.
This commit introduces the 'Nuclear Submarine' feature, allowing submarines to function as mobile launch platforms for atomic bombs. - Adds a new `NuclearSubmarineResearch` upgrade, which costs 3,000,000 gold and requires prior submarine research. - The 'Water 3' dummy button in the research panel is now replaced with this upgrade. - After researching, all of the player's submarines are capable of launching `AtomBomb` nukes. - **Launch Logic:** The core nuke launching logic in `PlayerImpl.ts` (`nukeSpawn` method) has been updated. It now includes submarines in its search for the closest available launcher, but only when the nuke type is `AtomBomb`. - **UI Enablement:** The `BuildMenu.ts` component is updated to correctly enable the Atom Bomb launch button if the player has a nuclear-capable submarine, even without a traditional missile silo. - **Cooldown:** The cooldown mechanism in `NukeExecution.ts` has been generalized to apply a cooldown to any launching unit (Silo or Submarine) by using the generic `launch()` method on the `Unit` class. - **Stealth Integration:** A submarine now becomes visible for the entire duration of its nuke cooldown. This is handled by a direct check in the rendering logic in `UnitLayer.ts` against the unit's cooldown status.
This provides a clear visual cue to a submarine's owner about its current visibility to other players. When a player's own submarine is not visible to any enemies (i.e., it is not pinging, attacking, detected, or on nuke cooldown), its sprite will be rendered at 75% of its normal size. When it becomes visible to others, it returns to 100% size. This is implemented by adding a `sizeMultiplier` parameter to the `drawSprite` method in `UnitLayer.ts` and conditionally calling it with the smaller size for the owner's hidden submarines.
This commit introduces two enhancements to the Fighter Jet AI when targeting submarines.
1. **Target Priority Change:**
- Submarines are now a higher priority target than Transport Ships, Warships, and Trade Ships, making them a more attractive target for an upgraded Fighter Jet.
2. **Periodic Visibility Targeting:**
- The targeting logic now correctly accounts for the submarine's periodic 3-second visibility ping.
- This was achieved by adding an `isPeriodicallyVisible()` method to the core `Unit` object, which leverages the existing `lastVisibleTick` property, and then calling this method from the Fighter Jet's target acquisition logic.
This commit integrates the submarine and nuclear submarine upgrades into the tech tree. The "Submarine Warfare" technology is added to unlock the submarine unit. The "Nuclear Submarines" technology is added to unlock the nuclear submarine upgrade.
This commit aligns the submarine's targeting logic with that of the warship, preventing it from attacking neutral or friendly units. Submarines will now only engage with units from players they are at war with.
The paratrooper launch is now blocked during the peace timer, preventing the unit from being created and flying to the destination. The paratrooper icon in the radial menu is now hidden when the peace timer is active.
- Adds Paratroopers as a level 2 parallel Air tech (`Air-2B`). - Researching this tech grants the `AirUpgrade1`, which enables paratrooper attacks. - Updates the `Air-3` tech to require either `Air-2` or the new `Air-2B`. - Fixes a failing test in `computeResearchLevel.test.ts` that was affected by the new tech.
Introduces a new 'City Anti-Air' upgrade, allowing cities to defend themselves against aerial threats like nukes and bombers. This system provides a reliable, deterministic defense against aerial attacks. Core Mechanics - **One-on-One Engagement:** When an enemy projectile enters the defense umbrella, the single closest available city engages it. This ensures only one defensive asset is used per target, preventing wasted cooldowns. - **Guaranteed Interception:** The system operates with a 100% success rate. An engaged target is guaranteed to be intercepted and destroyed. - **Cooldown System:** After intercepting a target, the city's anti-air system goes on a 30-second cooldown. A red circular border is rendered on the client to provide a clear visual indicator of this cooldown period. - **Unified Target Locking:** The system uses a `targetedBySAM` flag to 'claim' a projectile once it has been engaged. This ensures seamless coordination between city defenses and mobile SAM launchers, preventing multiple units from firing at the same target. Additional Features - **Bomber Interception:** In addition to nukes, the city anti-air system also targets and destroys incoming enemy bombers. - **AI Integration:** Nation bots automatically receive the City Anti-Air upgrade upon building their first SAM launcher, enhancing their defensive capabilities. - **UI Integration:** The upgrade is available for purchase in the Research panel.
The previous implementation did not correctly update the city's texture when the anti-air cooldown started, because the texture was being cached. This commit fixes the issue by including the cooldown state in the texture's cache key. This forces the texture to be re-created when the cooldown state changes, ensuring that the red border is displayed correctly.
### Functional Description
This commit introduces a new unlockable tech, "Warship AA Defenses," which equips Warships with a defensive anti-air (AA) missile system. This feature allows players to better protect
their naval fleets from aerial threats.
Once the tech is acquired, all of the player's Warships will automatically scan for and engage nearby enemy aircraft, including Bombers, Fighter Jets, and Cargo Planes. It is a convent
ional defensive system and does not intercept nuclear missiles. The system functions as a "mini-SAM," reusing the visual missile execution from SAM Launchers but with unique, balanced cha
racteristics.
**Mini-SAM Stats vs. Standard SAM:**
* **Range:** 60 tiles (75% of a standard SAM's 80-tile range).
* **Cooldown:** 50 ticks / 5.0 seconds (25% longer than a standard SAM's 40-tick / 4.0-second cooldown).
* **Hit Chance:** 80% base chance, identical to a standard SAM. This chance is further reduced proportionally to the Warship's own remaining health.
### Technical Description
The implementation is centered in `WarshipExecution.ts` and is designed for performance and alignment with existing game patterns.
1. **Configuration (`DefaultConfig.ts`, `Game.ts`, `Schemas.ts`):**
* A new `UpgradeType.WarshipAntiAir` enum and corresponding schema entries were added to make the upgrade available for purchase.
* New methods (`warshipAARange`, `warshipAACooldown`, `warshipAAScanInterval`, `warshipAAHittingChance`) were added to `DefaultConfig.ts` to allow for easy balancing of the AA syste
m's parameters.
2. **Core Logic (`WarshipExecution.ts`):**
* A new `scanAndEngageAircraft()` method is called on every tick. This logic is self-contained and does not interfere with the Warship's primary cannon cooldown or movement.
* **Performance:** The scan is throttled by `warshipAAScanInterval` (currently 0.5 seconds) to prevent running expensive checks on every tick. Target acquisition uses squared-distan
ce comparisons to avoid costly square root calculations.
* **Targeting:** A single-loop, map-based priority system (`Bomber` > `FighterJet` > `CargoPlane`) is used to efficiently select the highest-priority target without sorting. The sys
tem respects the `targetedBySAM` flag to prevent overkill from multiple AA units.
* **Hit Calculation:** Hit chance is determined by the configurable `warshipAAHittingChance()` and is further modified by the Warship's own health percentage, simulating reduced eff
ectiveness when damaged.
3. **Testing (`WarshipExecution.test.ts`):**
* A comprehensive test suite was created to validate all aspects of the new feature.
* Tests cover functionality with and without the upgrade, range and cooldown limits, correct target prioritization, and edge cases like ignoring nukes and preventing overkill.
* The test suite uses mocking for `PseudoRandom` and configuration values to ensure deterministic and reliable outcomes.
…m cherry-pick
This commit addresses TypeScript compilation errors that arose after cherry-picking the 'warship anti-air' feature. The errors were due to type mismatches in shared core logic (`src/core`) when interacting with client-side view models (`GameView`, `PlayerView`, `UnitView`).
Specifically, the following changes were made:
- **`src/core/game/Game.ts`**: Updated `Player.isFriendly` to accept `Player | PlayerView` to ensure compatibility across client and server contexts.
- **`src/core/game/GameView.ts`**:
- Modified `PlayerView.isFriendly`, `PlayerView.isAlliedWith`, and `PlayerView.isOnSameTeam` to correctly handle `Player | PlayerView` arguments, leveraging shared `smallID()` and `team()` methods.
- Added the `targetedBySAM()` method to `UnitView` to align with `Unit` interface.
- **`src/core/game/GameUpdates.ts`**: Added `targetedBySAM?: boolean;` to the `UnitUpdate` interface to support the new `UnitView` method.
These changes ensure type consistency in the shared core, allowing the warship anti-air feature to compile correctly.
This commit adds the "Warship Anti-Air" upgrade to the research tree at Sea Level 1. - The `RESEARCH_TECH_IDS` object in `src/core/tech/TechEffects.ts` has been updated to include `WARSHIP_ANTI_AIR: "Sea-1"`. - A new tech definition has been added to the `TECHS` object in `src/core/tech/TechEffects.ts` for the "Warship Anti-Air" upgrade. This includes the metadata (name and description) and the `onComplete` and `onRevoke` effects, which grant or remove the `UpgradeType.WarshipAntiAir` to the player.
### Functional Description
This commit enhances the anti-air (AA) defense systems of Warships, enabling them to target and shoot down Paratrooper planes.
Additionally, the Warship's AA targeting priority has been updated to treat Paratroopers as the highest-priority threat, reflecting their strategic importance.
### Technical Description
1. **Warship AA (`WarshipExecution.ts`):**
* The `nearbyUnits` scan array was updated to include `UnitType.Paratrooper`.
* The `priority` map was reordered to make Paratroopers the highest priority target.
* The corresponding unit test was updated to assert this new priority.
This commit enhances the anti-air (AA) defense systems of Warships, enabling them to target and shoot down Paratrooper planes.
Additionally, the Warship's AA targeting priority has been updated to treat Paratroopers as the highest-priority threat, reflecting their strategic importance.
1. **Warship AA (`WarshipExecution.ts`):**
* The `nearbyUnits` scan array was updated to include `UnitType.Paratrooper`.
* The `priority` map was reordered to make Paratroopers the highest priority target.
* The corresponding unit test was updated to assert this new priority.
This feature introduces a new purchasable upgrade, '''Fighter Anti-Ship,''' which enhances the strategic capabilities of air units. When a player purchases this upgrade, their Fighter Jets gain the ability to detect, target, and attack enemy naval units.
The targeting logic is prioritized to ensure fighters engage the most significant threats first. The new hierarchy is:
1. Enemy Aircraft (Bombers, other Fighters)
2. Warships
3. Transport Ships & Trade Ships
This creates a new dynamic between air and sea power, allowing for more diverse offensive and defensive strategies.
The implementation is centered around modifying the `FighterJetExecution` logic and exposing the new upgrade throughout the system.
- **`src/core/execution/FighterJetExecution.ts`**: The core logic resides here.
- The `findTargetUnit` method was refactored to conditionally expand the list of targetable units. It now checks if the fighter's owner has the `FighterJetNavalTargeting` upgrade and, if so, includes `Warship`, `TransportShip`, and `TradeShip` in its scan.
- A robust, priority-based targeting system was implemented to sort potential targets based on their strategic threat level.
- The `attackTarget` method was updated to apply different damage models based on the target type (e.g., instantly destroying transports, damaging warships).
- To improve performance, a 10-tick scanning cooldown was added to the main `tick` method, preventing the expensive `findTargetUnit` scan from running on every game tick.
- **Configuration & Schemas**:
- `src/core/game/Game.ts`: Added `FighterJetNavalTargeting` to the `UpgradeType` enum.
- `src/core/configuration/DefaultConfig.ts`: Defined the in-game cost for the new upgrade.
- `src/core/Schemas.ts`: Updated the `PurchaseUpgradeIntentSchema` to recognize and validate the new upgrade type.
- **Testing**:
- `tests/core/execution/FighterJet.test.ts`: A comprehensive test suite was created to validate the new functionality, including tests for behavior with and without the upgrade, correct target prioritization, and appropriate damage application. One test related to the targeting cooldown was removed due to environmental flakiness.
This commit introduces a significant refactoring of the fighter jet's targeting logic and its integration into the tech tree. The `FighterJetExecution` has been updated to use a more robust priority-based targeting system. The priority of targetable units has been reordered to ensure that fighter jets engage the most critical threats first. Additionally, the handling of `TransportShip` and `TradeShip` targets has been optimized to delete them directly, rather than creating a `ShellExecution`. The `FighterJetNavalTargeting` upgrade has been integrated into the tech tree as the "Air-1" tech. This change simplifies the upgrade system and makes the naval targeting capability a researchable technology. The test suite for `FighterJetExecution` has been updated to reflect these changes. The test for damaging a warship now accounts for the warship's self-healing, and the prioritization test now uses a more reliable setup with an enemy fighter jet.
Updates the `FighterJetExecution` to provide visual feedback when attacking trade and transport ships. Previously, these ships were instantly deleted with no corresponding attack visualization. This change makes fighters create a `ShellExecution` when targeting them, ensuring the attack is visible and consistent with engagements against other naval units like Warships.
This commit fixes a visual bug where fighter jets would leave a trail of pixels on the canvas. The issue was caused by a mismatch between the angle used for drawing the sprite and the angle used for clearing the sprite in the next frame. The clearing operation was using the new, smoothed angle, which resulted in not clearing the entire area of the previously drawn sprite. The fix involves: - Storing the angle of the sprite from the previous frame. - Using the stored "old" angle for the clearing operation. - Drawing the sprite with the new, smoothed angle. This ensures that the clearing and drawing operations are synchronized, and no pixel artifacts are left behind.
This commit refactors the investment slider logic to be more modular and reusable by introducing a new event-based communication system between the `ControlPanel2` and `ResearchTreeModal` components. The key changes are: - A new `InvestmentEvents.ts` file has been created to define custom events for investment-related actions, such as setting investment rates and toggling locks. This decouples the `ControlPanel2` and `ResearchTreeModal` components. - The `ControlPanel2.ts` file has been refactored to use the new `InvestmentEvents` to communicate with other components. The logic for handling investment changes has been centralized into the `applyInvestmentChange` and `commitInvestmentRates` functions. - The `ResearchTreeModal.ts` file has been updated to include its own investment sliders for research and roads. It now listens for `investment-sync` events to keep its sliders in sync with the `ControlPanel2` sliders and dispatches `investment-request-change` events when its sliders are changed. These changes improve the modularity and reusability of the investment slider logic and provide a better user experience by allowing users to control their investments from the research tree modal.
Creates a dedicated ResearchToggleButton layer that renders a fixed left-edge control mirroring the waffle button styling and exposing vertical 'RESEARCH' text. The new layer wires into GameRenderer so it receives game/eventBus references, hides itself until the player has spawned, and manages modal open/close state by talking directly to research-tree-modal. This lets us add the button without touching ControlPanel2 or the existing research tab logic. Adds the element to index.html so it exists in the DOM on load, bumps its z-index and spacing so clicks still register when the research modal is open.
Introduces a dedicated tech-unlock notification Lit layer that subscribes to player updates, queues newly researched techs, and renders the submarine-styled slide-out toast next to the research toggle. The component manages its own visibility, auto-dismiss timers, and reset lifecycle so it survives respawns without duplicating notifications. Wires the new element into GameRenderer and index.html so it receives the game/event bus references alongside the other UI layers.
Renames the ResearchTreeModal All tab to Overview and threads the new label through the tab ordering/helpers so behavior stays intact. Adds inline completion percentages to every tech in the overview grid using the same beaker-to-cost math as ControlPanel2, keeping the existing checkmarks for completed techs.
This commit removes the integrated "Research" tab and its associated content, including the "Research Tree" button, from the ControlPanel2. This refactoring aligns with the new dedicated vertical research toggle button, centralizing research access through a single, consistent entry point outside the main control panel. The changes include: - Updating the `activeTab` state and `_changeTab` method to no longer include "Research". - Removing the HTML rendering logic for the "Research" tab and its content. - Removing the `getTechNodes` import, as it is no longer needed in this component.
Each research tree card now renders its description block under the cost with wrapping, a fixed height, and scroll when needed, so players can scan summaries without hovering. Also re-anchored the tooltip under the card and ensured description slots reserve space even when empty.
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:
This Pull Request introduces a significant overhaul of the research tree user interface, transforming it into a more organized and user-friendly experience. It refactors existing components, adds new interactive elements, and enhances visual feedback for technology unlocks. The primary goal is to improve navigation, provide more immediate information, and streamline player interaction with the research system.
Visual and Functional Changes
ResearchTreeModal.ts) has been redesigned from a wide, multi-column layout into a tabbed interface. Players can now easily navigate between different research categories (Land, Sea, Air, Nuclear, Economy) and an "Overview" tab.ResearchTreeModal, allowing players to manage their investment rates without leaving the research view. These sliders are synchronized with the main control panel.ControlPanel2to centralize research access through the new dedicated vertical button.Technical Description
This PR involves several key architectural and component-level changes:
ResearchTreeModal.tsRefactoring:src/client/events/InvestmentEvents.tsto define custom events (investment-sync,investment-request-change) for decoupled communication between investment sliders.ControlPanel2.tswas refactored to centralize investment logic (applyInvestmentChange,commitInvestmentRates) and now dispatches/listens to these events.ResearchTreeModal.tsnow listens forinvestment-syncevents to keep its sliders updated and dispatchesinvestment-request-changeevents when its sliders are manipulated.ResearchToggleButton.tsComponent:GameRendererandindex.htmlto ensure proper placement and access to game state/event bus.ResearchTreeModaldirectly.TechUnlockNotification.tsComponent:ControlPanel2for consistency.ControlPanel2.tsCleanup:getTechNodesimport as it's no longer needed in this component.Please complete the following:
Please put your Discord username so you can be contacted if a bug or regression is found:
el_magico777