Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

P2: A timed rotation maneuver does nothing on a ship that had an earlier timed lateral maneuver

Open Beginner friendly
#7,914 3 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@vovosta is already working on this.

Since Oct 20, 2026.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
cpp, lua
Domain
game-dev

Research direction

The issue identifies the faulty rotational timer check in aicode.cpp, in ai_control_info_apply; read that function and compare its rotation condition with the lateral condition. Change the elapsed check so a live rotation window is recognized, then reproduce the timed lateral maneuver followed by a timed rotation and confirm both ships turn.

Written by the indexing model from the issue text.

Description

Problem

A timed rotation maneuver (ship-rot-maneuver with a duration, or the rotation half of ship-maneuver, or Lua ship:doManeuver) does nothing on a ship that earlier ran a timed lateral maneuver which has since expired. The same call on a ship that never had a lateral maneuver works. FREDders see a rotation that works in one mission and silently fails in another depending on what the ship did before.

The cause is a missing ! in aicode.cpp. In ai_control_info_apply the lateral check reads "never expires, or the lateral timer has NOT elapsed", but the rotational check reads "never expires, or the rotational timer HAS elapsed", so a live rotation window never counts as a rotational maneuver. Rotations are only applied while the lateral window counts as live. A lateral timer that was never set (0) counts as not elapsed, which is why a fresh ship rotates. Once any finite lateral maneuver on that ship has expired, both booleans are false during the rotation window and the override block is skipped.

Steps to reproduce

  1. FSO master 12a36dc1a (also current as of 76219fd1e; aicode.cpp is unchanged between them), release build, Linux, MediaVPs 5.0.2.
  2. In any mission, two hostile GTF Ulysses, A and B, both given a play-dead order so the AI does not steer. I created them from Lua with mn.createShip, facing +Z.
  3. Ship A: A:doManeuver(1000, 0,0,0,false, 0,0,100,false, 0) (forward thrust for 1 second). Wait at least 3 seconds for it to expire.
  4. Both ships: doManeuver(3000, 100,0,0,false, 0,0,0,false, 0) (full heading rotation for 3 seconds). The equivalent sexps are ship-lat-maneuver with duration 1000 and forward 100, then ship-rot-maneuver with duration 3000 and heading 100.
  5. After the 3 seconds, read each ship's forward vector (Orientation:getFvec()).

Expected vs. actual behavior

Expected: both ships have turned the same amount.

Actual: ship B (no earlier lateral maneuver) turned; its forward vector went from (0, 0, 1) to (0.895, -0.438, 0.090). Ship A (earlier 1 s lateral maneuver) did not move at all; its forward vector stayed (0, 0, 1). Both doManeuver calls returned true.

Proposed fixes

  1. Add the missing !. Make the rotational test in ai_control_info_apply read !timestamp_elapsed(aip->ai_override_rot_timestamp), matching the lateral test two lines above. One character.
  2. Fix 1 plus reset the two maneuver timers when a ship is created. init_ai_object does not touch ai_override_lat_timestamp or the rotational timer, so a reused AI slot can inherit an old expired timer; clearing both at creation removes the "works on fresh ships only" variability even for code paths that still read the lateral timer.
  3. Apply the two halves independently. Instead of one combined "any maneuver live" gate around the whole block, apply the rotational values when the rotational window is live and the lateral values when the lateral window is live. Clearer, but a larger edit to a block that the expiry code in ai_control_info_flags_upkeep already keeps mostly correct.
Dominant language
C++
Stars
488
Forks
184
Avg merge
2d 9h
Merged PRs (30d)
40

Getting set up

We have not checked this project's setup files yet. Start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from scp-fs2open/fs2open.github.com

All issues in scp-fs2open/fs2open.github.com

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.