Skip to content

Conversation

@ryanbarlow97
Copy link
Contributor

@ryanbarlow97 ryanbarlow97 commented Nov 11, 2025

Resolves #2434

Description:

Allows bomb direction to be inverted by pressing a hotkey - currently "U".

Check the issue for screenshots / videos.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

Please put your Discord username so you can be contacted if a bug or regression is found:

w.o.n

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 11, 2025

Warning

Rate limit exceeded

@ryanbarlow97 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 26 minutes and 35 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between fdafa19 and 95a5850.

📒 Files selected for processing (1)
  • src/client/graphics/GameRenderer.ts (3 hunks)

Walkthrough

Threads a new rocketDirectionUp flag from input (KeyU) through UI state, event bus, build intents, transport/schema, execution, and parabola pathfinding; adds SwapRocketDirectionEvent and updates renderer/layers to toggle and use the flag for upward/downward nuke arcs.

Changes

Cohort / File(s) Summary
Input & Event
src/client/InputHandler.ts
Adds exported SwapRocketDirectionEvent, binds KeyU as swapDirection, emits the event on keyup.
UI State
src/client/graphics/UIState.ts
Adds exported rocketDirectionUp: boolean to UIState.
Renderer & Layers
src/client/graphics/GameRenderer.ts, src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts, src/client/graphics/layers/StructureIconsLayer.ts, src/client/graphics/layers/BuildMenu.ts
Introduces shared uiState; passes it into layers; NukeTrajectoryPreviewLayer subscribes to SwapRocketDirectionEvent to toggle uiState.rocketDirectionUp and invalidate cached trajectory; BuildMenu/StructureIconsLayer include rocketDirectionUp in build intents for bomb units.
Transport & Event Shape
src/client/Transport.ts
BuildUnitIntentEvent constructor gains optional rocketDirectionUp?: boolean; outgoing build_unit payload includes the field.
Core Schemas
src/core/Schemas.ts
BuildUnitIntentSchema adds optional rocketDirectionUp?: boolean (affects BuildUnitIntent type).
Execution Pipeline
src/core/execution/ConstructionExecution.ts, src/core/execution/ExecutionManager.ts, src/core/execution/NukeExecution.ts
Thread rocketDirectionUp into ConstructionExecution and ExecutionManager; NukeExecution stores rocketDirectionUp (default true) and forwards it to parabola computation.
Pathfinding
src/core/pathfinding/PathFinding.ts
ParabolaPathFinder.computeControlPoints(...) adds directionUp parameter to flip vertical offset and clamps control points to map height.
Tests
tests/InputHandler.test.ts
Test options updated to include rocketDirectionUp: true for InputHandler construction.
Localization & Help
resources/lang/en.json, src/client/HelpModal.ts
Adds bomb_direction string and HelpModal hotkey row for the U key.

Sequence Diagram(s)

sequenceDiagram
    actor Player
    participant InputHandler
    participant EventBus
    participant UIState
    participant NukePreview as NukeTrajectoryPreviewLayer
    participant Parabola as ParabolaPathFinder
    participant ExecMgr as ExecutionManager
    participant NukeExec as NukeExecution

    Player->>InputHandler: release KeyU
    InputHandler->>EventBus: emit SwapRocketDirectionEvent
    EventBus->>NukePreview: deliver SwapRocketDirectionEvent
    NukePreview->>UIState: toggle rocketDirectionUp
    NukePreview->>NukePreview: invalidate cached trajectory
    NukePreview->>Parabola: computeControlPoints(orig,dst,..., directionUp=UIState.rocketDirectionUp)
    Parabola-->>NukePreview: control points

    Note right of ExecMgr: Build intent includes rocketDirectionUp when building bombs
    ExecMgr->>NukeExec: new NukeExecution(..., rocketDirectionUp)
    NukeExec->>Parabola: computeControlPoints(..., directionUp=rocketDirectionUp)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to:
    • Parabola sign, height clamping, and map-height assumptions in computeControlPoints.
    • Consistent optional handling and serialization of rocketDirectionUp across schema, transport, and events.
    • Event subscription lifecycle and shared uiState mutation in renderer/layers.
    • Backwards compatibility for build payloads missing the new field.

Possibly related PRs

  • SAM smart targeting #1618 — modifies parabola/pathfinding and NukeExecution similarly; likely overlaps in trajectory-direction logic.

Suggested labels

Feature - Frontend, Feature - Simulation

Suggested reviewers

  • DevelopingTom
  • scottanderson

Poem

U flips the arc, a tiny key,
preview redraws the sky to see,
build intent carries chosen sway,
execution nudges the rocket's way,
little toggle, big display 🚀

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Bomb Direction' is concise and directly describes the main feature: allowing bomb direction to be changed via hotkey.
Description check ✅ Passed The description clearly explains that the PR adds bomb direction inversion by pressing hotkey 'U', references issue #2434, and includes all required checklist completions.
Linked Issues check ✅ Passed The PR implements the core requirement from issue #2434: providing a hotkey (U) to change bomb arcs/direction, with all necessary code changes across input handling, trajectory calculation, and UI components.
Out of Scope Changes check ✅ Passed All changes are focused on the bomb direction feature: input handling for hotkey, UI state management, trajectory calculation with direction parameter, schema updates, and help modal documentation. No unrelated modifications detected.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
tests/InputHandler.test.ts (1)

40-40: Consider adding tests for SwapRocketDirectionEvent.

The rocketDirectionUp: true addition is correct to satisfy the updated UIState interface. However, there are no tests verifying that pressing the swap direction key (KeyU) actually emits a SwapRocketDirectionEvent.

Would you like me to generate a test case for the swap direction functionality?

src/client/graphics/layers/StructureIconsLayer.ts (1)

337-347: Extract a shared helper for rocket direction units

The same AtomBomb/HydrogenBomb check now lives here and in BuildMenu.ts. A tiny helper like isDirectionalNuke(unitType: UnitType): unitType is UnitType.AtomBomb | UnitType.HydrogenBomb (or a small readonly set) would keep the rule in one place and make future tweaks safer.

src/client/graphics/layers/BuildMenu.ts (1)

400-407: Reuse a helper for directional nukes

We now repeat the AtomBomb/HydrogenBomb guard here and in StructureIconsLayer. Pulling it into a small helper (for example isDirectionalNuke(unitType)) keeps the list of directional units in one place and stays friendly for future changes.

src/client/graphics/GameRenderer.ts (1)

52-56: Prefer type-safe uiState initialization

Casting with as UIState hides missing or extra fields. Declaring the variable with an explicit type (or satisfies UIState) keeps the compiler on our side:

-  const uiState = {
-    attackRatio: 20,
-    ghostStructure: null,
-    rocketDirectionUp: true,
-  } as UIState;
+  const uiState: UIState = {
+    attackRatio: 20,
+    ghostStructure: null,
+    rocketDirectionUp: true,
+  };

Simple change, but it saves us from silent shape drift later.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 34251c0 and b188c75.

📒 Files selected for processing (13)
  • src/client/InputHandler.ts (3 hunks)
  • src/client/Transport.ts (2 hunks)
  • src/client/graphics/GameRenderer.ts (3 hunks)
  • src/client/graphics/UIState.ts (1 hunks)
  • src/client/graphics/layers/BuildMenu.ts (3 hunks)
  • src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts (4 hunks)
  • src/client/graphics/layers/StructureIconsLayer.ts (1 hunks)
  • src/core/Schemas.ts (1 hunks)
  • src/core/execution/ConstructionExecution.ts (2 hunks)
  • src/core/execution/ExecutionManager.ts (1 hunks)
  • src/core/execution/NukeExecution.ts (2 hunks)
  • src/core/pathfinding/PathFinding.ts (2 hunks)
  • tests/InputHandler.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-08-24T11:13:08.495Z
Learnt from: DevelopingTom
Repo: openfrontio/OpenFrontIO PR: 1900
File: src/core/execution/SAMLauncherExecution.ts:103-111
Timestamp: 2025-08-24T11:13:08.495Z
Learning: In SAMLauncherExecution.ts, the cached target bug can only occur if: 1) SAM is not on cooldown when nuke is in range, 2) SAM goes on cooldown right after computing trajectory, 3) SAM becomes available again before nuke explodes. This is not possible with current cooldown values but the fix is still valuable for robustness.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts
📚 Learning: 2025-10-20T20:15:28.858Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:51-51
Timestamp: 2025-10-20T20:15:28.858Z
Learning: In src/core/execution/FakeHumanExecution.ts, game balance constants like MIRV_COOLDOWN_TICKS, MIRV_HESITATION_ODDS, VICTORY_DENIAL_TEAM_THRESHOLD, VICTORY_DENIAL_INDIVIDUAL_THRESHOLD, and STEAMROLL_CITY_GAP_MULTIPLIER are experimental tuning parameters subject to frequent change during balance testing. Do not flag changes to these values as issues or compare them against previous values.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/core/execution/ExecutionManager.ts
  • src/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-27T09:47:26.395Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:770-795
Timestamp: 2025-10-27T09:47:26.395Z
Learning: In src/core/execution/FakeHumanExecution.ts, the selectSteamrollStopTarget() method intentionally allows MIRV targeting when secondHighest city count is 0 (e.g., nuclear endgame scenarios where structures are destroyed). This is valid game design—"if you can afford it, you're good to go"—and should not be flagged as requiring a guard condition.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-18T17:54:01.311Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:172-173
Timestamp: 2025-10-18T17:54:01.311Z
Learning: In src/core/execution/FakeHumanExecution.ts, MIRVs and ground attacks should not be mutually exclusive. The considerMIRV() method should not short-circuit maybeAttack() - both actions can occur in the same tick.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/core/execution/ExecutionManager.ts
  • src/core/execution/ConstructionExecution.ts
📚 Learning: 2025-05-18T23:36:12.847Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from UnitType values (specifically bomb-related values like AtomBomb, HydrogenBomb, MIRV, and MIRVWarhead) rather than a separate enum. This means comparing NukeType values against UnitType values in switch statements is valid and intentional.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-18T11:00:57.142Z
Learnt from: NewYearNewPhil
Repo: openfrontio/OpenFrontIO PR: 2230
File: src/client/graphics/GameRenderer.ts:269-277
Timestamp: 2025-10-18T11:00:57.142Z
Learning: In src/client/graphics/GameRenderer.ts, the GameRecapCapture implementation does not use setCaptureRenderEnabled on layers. Instead, it uses RecapCaptureSurface.capture() to render capture layers (TerrainLayer, TerritoryLayer, RailroadLayer, StructureIconsLayer, UnitLayer) directly to an off-screen canvas without requiring layer-level capture mode methods.

Applied to files:

  • src/client/graphics/GameRenderer.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/graphics/GameRenderer.ts
📚 Learning: 2025-08-12T00:31:50.144Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 1752
File: src/core/game/Game.ts:750-752
Timestamp: 2025-08-12T00:31:50.144Z
Learning: In the OpenFrontIO codebase, changes to the PlayerInteraction interface (like adding canDonateGold and canDonateTroops flags) do not require corresponding updates to src/core/Schemas.ts or server serialization code.

Applied to files:

  • src/core/Schemas.ts
📚 Learning: 2025-05-18T23:36:12.847Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from specific UnitType enum values (AtomBomb, HydrogenBomb, MIRV, MIRVWarhead). This means that comparisons in switch statements between a NukeType parameter and UnitType enum values are valid and will work correctly at runtime.

Applied to files:

  • src/core/execution/ConstructionExecution.ts
🧬 Code graph analysis (7)
src/client/InputHandler.ts (1)
src/core/EventBus.ts (1)
  • GameEvent (1-1)
src/client/graphics/layers/BuildMenu.ts (2)
src/client/graphics/UIState.ts (1)
  • UIState (3-7)
src/client/Transport.ts (1)
  • BuildUnitIntentEvent (88-94)
src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts (2)
src/client/graphics/UIState.ts (1)
  • UIState (3-7)
src/client/InputHandler.ts (1)
  • SwapRocketDirectionEvent (92-92)
src/core/execution/ExecutionManager.ts (1)
src/core/execution/ConstructionExecution.ts (1)
  • ConstructionExecution (21-160)
src/client/graphics/GameRenderer.ts (2)
src/client/graphics/UIState.ts (1)
  • UIState (3-7)
src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts (1)
  • NukeTrajectoryPreviewLayer (19-275)
src/client/graphics/layers/StructureIconsLayer.ts (1)
src/client/Transport.ts (1)
  • BuildUnitIntentEvent (88-94)
src/core/execution/ConstructionExecution.ts (1)
src/core/execution/NukeExecution.ts (1)
  • NukeExecution (19-338)
🔇 Additional comments (11)
src/client/InputHandler.ts (2)

92-93: LGTM!

Event definition follows the established pattern for parameterless events in this codebase.


205-205: LGTM!

Keybind definition follows the existing pattern and can be customized by users via localStorage.

src/client/graphics/UIState.ts (1)

6-6: LGTM!

Adding rocketDirectionUp to the UIState interface is the correct approach for shared UI state. The property is appropriately typed and named.

src/core/execution/ExecutionManager.ts (1)

108-113: LGTM!

The rocketDirectionUp parameter is correctly threaded from the intent to the ConstructionExecution. The optional parameter will be undefined when not provided, which aligns with the ConstructionExecution constructor signature.

src/core/execution/ConstructionExecution.ts (2)

34-34: LGTM!

The optional rocketDirectionUp parameter is correctly added to the constructor, providing backward compatibility when the parameter is not provided.


108-116: No changes needed—MIRV direction control is intentional design.

MirvExecution deliberately accepts only (player, dst) parameters with no direction control, unlike NukeExecution which accepts rocketDirectionUp. This is by design: AtomBomb and HydrogenBomb use a single directional arc (up or down), while MIRV uses intelligent dispersal across multiple targets in a scatter pattern. Both weapon types work as intended.

src/core/Schemas.ts (1)

305-305: LGTM!

The optional rocketDirectionUp field is correctly added to the BuildUnitIntentSchema. Making it optional ensures backward compatibility with existing code that doesn't provide this parameter.

src/client/Transport.ts (2)

92-92: LGTM!

The optional rocketDirectionUp parameter is correctly added to BuildUnitIntentEvent, maintaining backward compatibility for existing callers.


553-553: LGTM!

The rocketDirectionUp parameter is correctly propagated from the event to the intent payload. When undefined, this will result in the field being omitted from the payload or serialized as undefined, which aligns with the optional schema definition.

src/core/execution/NukeExecution.ts (2)

33-33: LGTM!

The default value of true for rocketDirectionUp preserves the existing upward trajectory behavior, ensuring backward compatibility for code paths that don't explicitly provide this parameter.


119-119: LGTM!

The rocketDirectionUp parameter is correctly passed to the pathfinder, enabling direction-aware trajectory computation as intended by this PR.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 11, 2025
@ryanbarlow97 ryanbarlow97 marked this pull request as ready for review November 11, 2025 21:47
@ryanbarlow97 ryanbarlow97 requested a review from a team as a code owner November 11, 2025 21:47
@HimangshuPronoy
Copy link

This seems good yea

Copy link

@HimangshuPronoy HimangshuPronoy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything seems good. high quality code.

@ryanbarlow97
Copy link
Contributor Author

Everything seems good. high quality code.

cheers

@ryanbarlow97
Copy link
Contributor Author

I've just added the "U" hotkey instruction to the helpmodal + en.json list as I forgot to do this

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d755514 and 2a07538.

📒 Files selected for processing (2)
  • resources/lang/en.json (1 hunks)
  • src/client/HelpModal.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from UnitType values (specifically bomb-related values like AtomBomb, HydrogenBomb, MIRV, and MIRVWarhead) rather than a separate enum. This means comparing NukeType values against UnitType values in switch statements is valid and intentional.
🧬 Code graph analysis (1)
src/client/HelpModal.ts (2)
src/client/Utils.ts (1)
  • translateText (92-147)
src/client/LangSelector.ts (1)
  • translateText (254-274)
🔇 Additional comments (1)
src/client/HelpModal.ts (1)

58-61: LGTM!

The hotkey table row is correctly implemented and follows the established pattern. The translation key properly references the new entry in en.json.

@ryanbarlow97 ryanbarlow97 added this to the v28 milestone Nov 20, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/core/execution/NukeExecution.ts (1)

26-34: Good default preserves existing behavior.

The default true ensures backward compatibility—existing callers that do not specify direction will continue to get the upward arc trajectory.

One observation: this constructor now has 7 positional parameters. If more optional fields are added later, consider grouping optional params into an options object for readability. Not blocking for this PR.

Example pattern for future consideration:

interface NukeOptions {
  src?: TileRef | null;
  speed?: number;
  waitTicks?: number;
  rocketDirectionUp?: boolean;
}

constructor(
  private nukeType: NukeType,
  private player: Player,
  private dst: TileRef,
  options: NukeOptions = {},
) {
  this.src = options.src ?? null;
  this.speed = options.speed ?? -1;
  this.waitTicks = options.waitTicks ?? 0;
  this.rocketDirectionUp = options.rocketDirectionUp ?? true;
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between de4f36f and c72eeb9.

📒 Files selected for processing (4)
  • resources/lang/en.json (1 hunks)
  • src/client/graphics/layers/StructureIconsLayer.ts (1 hunks)
  • src/core/execution/ConstructionExecution.ts (2 hunks)
  • src/core/execution/NukeExecution.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/client/graphics/layers/StructureIconsLayer.ts
  • resources/lang/en.json
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-08-24T11:13:08.495Z
Learnt from: DevelopingTom
Repo: openfrontio/OpenFrontIO PR: 1900
File: src/core/execution/SAMLauncherExecution.ts:103-111
Timestamp: 2025-08-24T11:13:08.495Z
Learning: In SAMLauncherExecution.ts, the cached target bug can only occur if: 1) SAM is not on cooldown when nuke is in range, 2) SAM goes on cooldown right after computing trajectory, 3) SAM becomes available again before nuke explodes. This is not possible with current cooldown values but the fix is still valuable for robustness.

Applied to files:

  • src/core/execution/NukeExecution.ts
📚 Learning: 2025-10-20T20:15:28.858Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:51-51
Timestamp: 2025-10-20T20:15:28.858Z
Learning: In src/core/execution/FakeHumanExecution.ts, game balance constants like MIRV_COOLDOWN_TICKS, MIRV_HESITATION_ODDS, VICTORY_DENIAL_TEAM_THRESHOLD, VICTORY_DENIAL_INDIVIDUAL_THRESHOLD, and STEAMROLL_CITY_GAP_MULTIPLIER are experimental tuning parameters subject to frequent change during balance testing. Do not flag changes to these values as issues or compare them against previous values.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-27T09:47:26.395Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:770-795
Timestamp: 2025-10-27T09:47:26.395Z
Learning: In src/core/execution/FakeHumanExecution.ts, the selectSteamrollStopTarget() method intentionally allows MIRV targeting when secondHighest city count is 0 (e.g., nuclear endgame scenarios where structures are destroyed). This is valid game design—"if you can afford it, you're good to go"—and should not be flagged as requiring a guard condition.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/core/execution/ConstructionExecution.ts
📚 Learning: 2025-10-18T17:54:01.311Z
Learnt from: sambokai
Repo: openfrontio/OpenFrontIO PR: 2225
File: src/core/execution/FakeHumanExecution.ts:172-173
Timestamp: 2025-10-18T17:54:01.311Z
Learning: In src/core/execution/FakeHumanExecution.ts, MIRVs and ground attacks should not be mutually exclusive. The considerMIRV() method should not short-circuit maybeAttack() - both actions can occur in the same tick.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/core/execution/ConstructionExecution.ts
📚 Learning: 2025-05-18T23:36:12.847Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from UnitType values (specifically bomb-related values like AtomBomb, HydrogenBomb, MIRV, and MIRVWarhead) rather than a separate enum. This means comparing NukeType values against UnitType values in switch statements is valid and intentional.

Applied to files:

  • src/core/execution/NukeExecution.ts
  • src/core/execution/ConstructionExecution.ts
📚 Learning: 2025-05-18T23:36:12.847Z
Learnt from: scottanderson
Repo: openfrontio/OpenFrontIO PR: 784
File: src/core/game/StatsImpl.ts:143-159
Timestamp: 2025-05-18T23:36:12.847Z
Learning: In this codebase, NukeType is a union type derived from specific UnitType enum values (AtomBomb, HydrogenBomb, MIRV, MIRVWarhead). This means that comparisons in switch statements between a NukeType parameter and UnitType enum values are valid and will work correctly at runtime.

Applied to files:

  • src/core/execution/ConstructionExecution.ts
🧬 Code graph analysis (1)
src/core/execution/ConstructionExecution.ts (1)
src/core/execution/NukeExecution.ts (1)
  • NukeExecution (19-338)
🔇 Additional comments (3)
src/core/execution/ConstructionExecution.ts (2)

20-25: Clean addition of the direction parameter.

The optional rocketDirectionUp parameter integrates well with the existing constructor signature. When not provided, it stays undefined, which will trigger the default value (true) in the downstream NukeExecution constructor—preserving backward compatibility.


105-120: Correct propagation to NukeExecution for AtomBomb and HydrogenBomb.

The rocketDirectionUp flag is passed through correctly. Note that MirvExecution (line 120) does not receive this flag, which appears intentional since MIRVs have distinct trajectory behavior that ignores this parameter.

src/core/execution/NukeExecution.ts (1)

114-120: Trajectory computation correctly uses the direction flag.

The rocketDirectionUp value is passed to computeControlPoints as the 5th argument, enabling the parabola pathfinder to compute either upward or downward arcs based on user input. This integrates cleanly with the existing trajectory logic.

Copilot AI review requested due to automatic review settings December 4, 2025 17:53
Copilot finished reviewing on behalf of ryanbarlow97 December 4, 2025 17:55
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a bomb direction toggle feature that allows players to invert the trajectory arc of Atom and Hydrogen bombs by pressing the "U" hotkey. The feature adds UI state management for tracking the rocket direction preference and propagates it through the execution pipeline to control the parabolic path calculation.

  • Adds rocketDirectionUp boolean to UIState to track the current bomb trajectory preference
  • Implements hotkey "U" to toggle between upward and downward bomb arcs
  • Updates pathfinding logic to support inverted trajectories with proper map boundary constraints

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/core/pathfinding/PathFinding.ts Adds directionUp parameter to computeControlPoints to control trajectory direction with boundary clamping
src/core/execution/NukeExecution.ts Passes rocketDirectionUp parameter through to pathfinding for Atom/Hydrogen bombs
src/core/execution/ConstructionExecution.ts Accepts and forwards rocketDirectionUp to NukeExecution for Atom/Hydrogen bombs
src/core/execution/ExecutionManager.ts Extracts rocketDirectionUp from intent and passes to ConstructionExecution
src/core/Schemas.ts Adds optional rocketDirectionUp field to BuildUnitIntent schema
src/client/graphics/UIState.ts Adds rocketDirectionUp boolean field to track user preference
src/client/graphics/GameRenderer.ts Initializes rocketDirectionUp to true and wires uiState to BuildMenu
src/client/graphics/layers/NukeTrajectoryPreviewLayer.ts Handles SwapRocketDirectionEvent and uses uiState for preview trajectory calculation
src/client/graphics/layers/StructureIconsLayer.ts Includes rocketDirectionUp in BuildUnitIntentEvent for Atom/Hydrogen bombs
src/client/graphics/layers/BuildMenu.ts Includes rocketDirectionUp in BuildUnitIntentEvent for Atom/Hydrogen bombs
src/client/Transport.ts Adds rocketDirectionUp parameter to BuildUnitIntentEvent and transport layer
src/client/InputHandler.ts Adds swapDirection keybind and emits SwapRocketDirectionEvent on "U" press
src/client/HelpModal.ts Adds help entry for "U" key bomb direction toggle
resources/lang/en.json Adds localization text for bomb direction feature
tests/InputHandler.test.ts Updates test to include rocketDirectionUp in UIState initialization

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bomb Direction

4 participants