Classic bug: Damaged Cybertron target-flee ordering
| Bug ID | GE-BUG-017 |
|---|---|
| Affected versions | Classic 3.2e and published classic source |
| Status | Verified in source and exposed by ge-next flee messages |
| Fixed in | ge-next 0.2.6 |
| Primary source | GECYBS.C: cyb_lives(), cyb_check_damage(), and cyb_check_lockon() |
Summary
A heavily damaged classic Cybertron with no current target can select a new cybmine, begin pursuing that ship, and then almost immediately enter its damage-driven flee behavior. The player may appear to attract an approaching Cybertron only for it to turn and run before the encounter begins.
The defect is not that fleeing from an established attacker is wrong. A Cybertron above the flee threshold should attempt to escape a fight already in progress. The defect is that an idle Cybertron already damaged beyond that threshold is still allowed to pick a new fight.
Visible symptom
Classic has damage-driven escape movement, but its generic Cybertron chatter does not clearly identify the transition as a retreat. The contradictory state change can therefore look like ordinary unpredictable NPC movement.
With explicit FLEE messages, the sequence becomes clear: a Cybertron announces or begins an approach toward a newly selected target, then shortly afterward announces that it is fleeing even though it has not reached or fought that target. The messages expose the state conflict; they do not create it.
Relevant state
cybmine identifies the ship a Cybertron is pursuing. A value of 255 means it currently has no target.
CYB_MINDAM is 75. When a Cybertron's damage is greater than 75 and it has a target, classic gives the damage-response routine a 1-in-10 chance on each Cybertron behavior update to flee. That response can also drop a mine or activate a jammer, then sets:
- requested speed to the Cybertron's normal top speed;
- requested heading to a random direction; and
holdcourseto a random duration from 5 through 14 updates.
While holdcourse is positive, lock-on processing counts it down and returns without steering back toward the target.
Update order
Classic processes the damage response before target acquisition during each Cybertron behavior update:
cyb_lives()callscyb_check_damage().- It then calls
cyb_check_lockon().
That order still creates the bug because the two routines use different prerequisites.
First update: damage response is skipped
Suppose a Cybertron has 80 damage and no target:
damage = 80 cybmine = 255
cyb_check_damage() requires both damage above 75 and cybmine < 255. Because no target exists yet, it does nothing. The Cybertron does not enter a neutral recovery or flee state.
cyb_check_lockon() then sees cybmine == 255, scans eligible players, selects the closest unclaimed target, and writes that channel to cybmine. Classic does not test damage before making this selection. It immediately configures pursuit speed and heading and may produce approach behavior.
Following update: the new target enables fleeing
On a later Cybertron update, the same ship still has damage above 75, but now cybmine contains the newly selected player. The damage routine's missing prerequisite has been supplied by the lock-on routine.
When the 1-in-10 flee roll succeeds, the Cybertron abandons its pursuit movement, chooses a random escape heading, and holds that course. From the player's perspective, the Cybertron has selected them only to flee from them.
The retreat may happen on the first update after acquisition or after several updates, depending on the random roll. With explicit approach and flee messages, even a short delay looks like a direct contradiction: the Cybertron announces interest in a ship it was already too damaged to engage sensibly.
Repeated state conflict
Classic's flee response does not clear cybmine. It temporarily overrides movement with holdcourse, but the same target remains assigned.
While damage remains above 75:
- another successful flee roll can select a new random escape heading and reset the hold duration;
- updates without a flee roll allow
cyb_check_lockon()to count down the existing hold; - when the hold expires, pursuit can resume toward the same target; and
- a later damage roll can send the Cybertron fleeing again.
The Cybertron can therefore oscillate between pursuing and escaping from a player who did nothing to initiate the encounter. Passive repair may eventually reduce damage below the threshold, but until then its target and movement states disagree about whether it wants a fight.
Gameplay consequences
The defect produces more than an odd message sequence:
- a badly damaged Cybertron can claim a player as its target even though it is not prepared to engage;
- that claim participates in classic's target-claim limits and can keep another Cybertron from selecting the player;
- pursuit can carry the damaged Cybertron toward the player before a flee roll occurs;
- the damage response may lay mines or jam while escaping from a newly acquired, uninvolved target;
- repeated pursuit and flee transitions make Cybertron navigation look erratic; and
- players may waste time reacting to an announced approach that the Cybertron immediately abandons.
Because classic lacked a clear FLEE announcement, players could reasonably interpret this as random AI behavior rather than a damaged ship repeatedly entering incompatible states.
Correction in ge-next 0.2.6
ge-next added the damage requirement directly to new-target acquisition. The target search is gated by this condition from the 0.2.6 code:
ptr->cybmine == (byte)255 && ptr->damage <= CYB_MINDAM
Only an untargeted Cybertron at or below the damage threshold searches for a new target. A Cybertron that already has a legitimate target can still execute damage-driven escape behavior. A Cybertron with no target and more than 75 damage will not create a fresh pursuit merely to flee from it on a later update.
This is a narrow state-transition correction rather than a general ban on damaged Cybertrons fighting. Existing combat attribution remains intact, and an attacker that damaged the Cybertron can remain its target. The guard applies only when the AI would otherwise search for a new opponent.
Later flee refinements
Subsequent ge-next work made the flee state itself more coherent:
- the initial flee heading is based roughly opposite the current target rather than being completely random;
- ordinary attack chatter is suppressed while fleeing or preparing to flee;
- the target and related message state are cleared when the flee interval finishes; and
- damaged Cybertrons avoid immediately replacing a cleared target until their damage is back within the engagement threshold.
Those changes improve the quality and visibility of retreat behavior. The essential Bug 17 correction is the 0.2.6 guard that prevents an already heavily damaged, untargeted Cybertron from selecting a new pursuit.
Porting guidance
AI state transitions should be validated when a new state is entered, not only by an earlier routine whose prerequisites may not yet exist. A target-selection routine should ask whether the NPC is currently capable of pursuing, while a flee routine should distinguish an established attacker from an arbitrary target selected moments earlier.
Logging or messaging explicit state transitions such as IDLE, PURSUIT, ATTACK, and FLEE is valuable during development. The FLEE messages made this legacy problem visible because they revealed two individually plausible decisions that were invalid when placed next to each other.
Home · Play · Reference · Versions & history · Sysop · Development · Classic bugs